Android Question B4XTable add Signature (Firm) Column

MicroDrie

Well-Known Member
Licensed User
Longtime User
You refer to an application example where the flags are in the read-only asset directory. Now, over the years, reading a directory on Android has become increasingly difficult. What you doesn't tell is if you want to do the reading and saving to the same app in the flags example. In that case you can start writing to XUI.setdatafolder and read it back with XUI.DefaultFolder. The disadvantage is that with the removal of your app, all signatures also disappear.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
There are several aspects to this question.

The UI part: I recommend you to use B4XSignatureTemplate + B4XDialog. You can then get the image and show it in an ImageView inside the cell.

Saving the data:
B4XTable is a visual element. It is really up to you to decide where the data comes from and where it is saved. You can save the images as separate files or convert to bytes and insert to a database.
 
Upvote 0

mike1967

Active Member
Licensed User
Longtime User
Hello, i try to implement load save and display signature (firm) in a column of a B4XTable but when run return me an error on line 232.

code:
a As Map
    Private xui As XUI
    Private editCol As B4XTableColumn
    Private const CSVFile As String = "naspi.csv"
    Dim data As List
     Private provider As FileProvider
    Private old_filefirma,current_filefirma As String =""
    Private signature_column As B4XTableColumn
    
End Sub

'You can add more parameters here.
Public Sub Initialize As Object
    B4XPages.GetManager.LogEvents = True
    Return Me
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("1")
    xui.SetDataFolder(File.DirInternal)
    Log(xui.DefaultFolder)

    editCol = B4XTable1.AddColumn("Edit", B4XTable1.COLUMN_TYPE_TEXT)
    editCol.Sortable = False
    editCol.Width = 127dip
    B4XTable1.RowHeight = 50dip
    B4XTable1.HeadersHeight =70dip
    
    B4XTable1.AddColumn("Naspo Numero", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Data Verifica", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Ubicazione", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Livello", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Riferimento Planimetria", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Naspo presente ed indicato con cartello", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Pannello frontale integro e facilmente apribile", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Etichette presenti e correttamente compilate", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Componenti integri", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Lancia presente", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Esito della Verifica", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Prossima Verifica entro il", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Incaricato", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Qualifica", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Responsabile", B4XTable1.COLUMN_TYPE_TEXT)
    signature_column=B4XTable1.AddColumn("Firma",B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.NumberOfFrozenColumns= 1
    
    xSelections.Initialize(B4XTable1)
    xSelections.Mode = xSelections.MODE_SINGLE_LINE_PERMANENT
    xSelections.SelectionColor=xui.Color_Red     'you can change the color of the row selected with this
    
    For i = 1 To signature_column.CellsLayouts.Size - 1
        Dim pnl As B4XView = signature_column.CellsLayouts.Get(i)
        Dim iv As B4XView
        pnl.AddView(iv, 5dip, 5dip, signature_column.Width - 10dip, B4XTable1.RowHeight - 10dip)
    Next
    
    LoadData
    PrefDialog.Initialize(Root, "Schede verifiche di sorveglianza", 300dip, 300dip)
    PrefDialog.LoadFromJson(File.ReadString(File.DirAssets, "naspo.json"))
    PrefDialog.Dialog.BlurBackground=True
    PrefDialog.Dialog.PutAtTop=True
    PrefDialog.Dialog.TitleBarColor=Colors.Red
    PrefDialog.Dialog.TitleBarTextColor=Colors.White
    PrefDialog.Dialog.TitleBarHeight=130
    PrefDialog.Dialog.ButtonsColor=Colors.Red
    PrefDialog.Dialog.ButtonsTextColor=Colors.White
    PrefDialog.SearchTemplate.Resize(90%x,50%y)
    PrefDialog.SearchTemplate.SearchField.HintText="Cerca..."
    PrefDialog.SearchTemplate.SearchField.Update
    PrefDialog.SearchTemplate.MaxNumberOfItemsToShow = 300
    B4XTable1.MaximumRowsPerPage = 10
    B4XTable1.BuildLayoutsCache(B4XTable1.MaximumRowsPerPage)
    For i = 1 To editCol.CellsLayouts.Size -  1
        Dim p As B4XView = editCol.CellsLayouts.Get(i)
        p.AddView(CreateButton("btnEdit", Chr(0xF044)), 2dip, 5dip, 40dip, 40dip)
        p.AddView(CreateButton("btnDelete", Chr(0xF00D)), 44dip, 5dip, 40dip, 40dip)
        p.AddView(CreateButton("btnDuplicate",Chr(0xF0C5)), 85dip, 5dip, 40dip, 40dip)
    Next
    provider.Initialize
End Sub

Private Sub B4XPage_Background
'    'ExportTableToCSV
End Sub

Sub LoadData
    
    If File.Exists(xui.DefaultFolder, CSVFile) Then
        Dim su As StringUtils
        data = su.LoadCSV(xui.DefaultFolder, CSVFile, ",")
    Else
        data.Initialize
    End If
    B4XTable1.HeaderFont = xui.CreateDefaultBoldFont(14)
    B4XTable1.LabelsFont = xui.CreateDefaultFont(14)
    B4XTable1.SetData(data)
End Sub

Sub btnAdd_Click
    ShowDialog(CreateMap(), 0)
End Sub

Sub btnPrint_Click
    If File.Exists(provider.SharedFolder,"report.pdf")=True Then
        File.Delete(provider.SharedFolder,"report.pdf")
    End If
    Dim html2pdf As PalmoHtmlToPdf
    html2pdf.Initialize("html2pdf")
    html2pdf.ConvertFromString(ExportToHtml(B4XTable1),provider.SharedFolder,"report.pdf")
    Sleep(0)
    
    
End Sub

Sub btnDelete_Click
    Dim RowId As Long = GetRowId(Sender)
    Dim Item As Map = B4XTable1.GetRow(RowId)
    Dim sf As Object = xui.Msgbox2Async($"Cancello Naspo n.ro: ${Item.Get("Naspo Numero")}?"$, "", "Si", "", "No", Null)
    Wait For (sf) Msgbox_Result (Result As Int)
    If Result = xui.DialogResponse_Positive Then
        Dim filefirma As String
        filefirma=Item.Get("Incaricato") & "_" & Item.Get("Naspo Numero") & "_" & Item.Get("Data") & ".png"
        If File.Exists(File.DirInternal,filefirma)=True Then
            File.Delete(File.DirInternal,filefirma)
        End If
        B4XTable1.sql1.ExecNonQuery2("DELETE FROM data WHERE rowid = ?", Array(RowId))
        B4XTable1.UpdateTableCounters
        
        ExportTableToCSV
    End If
End Sub

Sub btnEdit_Click
    Dim RowId As Long = GetRowId(Sender)
    Dim Item As Map = B4XTable1.GetRow(RowId)
    old_filefirma=Item.Get("Incaricato") & "_" & Item.Get("Naspo Numero") & "_" & Item.Get("Data") & ".png"
    Dim swap As Map
    swap.Initialize
    DateTime.DateFormat="dd-MM-yyyy"
    
    swap.Put("naspo_numero",Item.Get("Naspo Numero"))
    swap.Put("data",DateTime.DateParse(Item.Get("Data Verifica")))
    swap.Put("ubicazione",Item.Get("Ubicazione"))
    swap.Put("livello",Item.Get("Livello"))
    swap.Put("riferimenti_planimetria",Item.Get("Riferimento Planimetria"))
    swap.Put("check1",IIf(Item.Get("Naspo presente ed indicato con cartello")="Positivo",True,False))
    swap.Put("check2",IIf(Item.Get("Pannello frontale integro e facilmente apribile")="Positivo",True,False))
    swap.Put("check3",IIf(Item.Get("Etichette presenti e correttamente compilate")="Positivo",True,False))
    swap.Put("check4",IIf(Item.Get("Componenti integri")="Positivo",True,False))
    swap.Put("check5",IIf(Item.Get("Lancia presente")="Positivo",True,False))
    swap.Put("esito",Item.Get("Esito della Verifica"))
    swap.Put("data_next",DateTime.DateParse(Item.Get("Prossima Verifica entro il")))
    swap.Put("incaricato",Item.Get("Incaricato"))
    swap.Put("qualifica",Item.Get("Qualifica"))
    swap.Put("responsabile",Item.Get("Responsabile"))
    swap.Put("firma",Item.Get("Firma"))
    
    ShowDialog(swap, RowId)
End Sub

Sub btnDuplicate_Click
    Dim RowId As Long = GetRowId(Sender)
    Dim Item As Map = B4XTable1.GetRow(RowId)
    Dim swap As Map
    swap.Initialize
    DateTime.DateFormat="dd-MM-yyyy"
    
    swap.Put("naspo_numero",Item.Get("Naspo Numero"))
    swap.Put("data",DateTime.DateParse(Item.Get("Data Verifica")))
    swap.Put("ubicazione",Item.Get("Ubicazione"))
    swap.Put("livello",Item.Get("Livello"))
    swap.Put("riferimenti_planimetria",Item.Get("Riferimento Planimetria"))
    swap.Put("check1",IIf(Item.Get("Naspo presente ed indicato con cartello")="Positivo",True,False))
    swap.Put("check2",IIf(Item.Get("Pannello frontale integro e facilmente apribile")="Positivo",True,False))
    swap.Put("check3",IIf(Item.Get("Etichette presenti e correttamente compilate")="Positivo",True,False))
    swap.Put("check4",IIf(Item.Get("Componenti integri")="Positivo",True,False))
    swap.Put("check5",IIf(Item.Get("Lancia presente")="Positivo",True,False))
    swap.Put("esito",Item.Get("Esito della Verifica"))
    swap.Put("data_next",DateTime.DateParse(Item.Get("Prossima Verifica entro il")))
    swap.Put("incaricato",Item.Get("Incaricato"))
    swap.Put("qualifica",Item.Get("Qualifica"))
    swap.Put("responsabile",Item.Get("Responsabile"))
    swap.Put("firma",Item.Get("Firma"))
    
    ShowDialog(swap, 0) 'RowId = 0 means that a new item will be created
End Sub

Sub GetRowId (View As B4XView) As Long
    Dim RowIndex As Int = editCol.CellsLayouts.IndexOf(View.Parent)
    Dim RowId As Long = B4XTable1.VisibleRowIds.Get(RowIndex  - 1) ' 1 because of the header
    Return RowId
End Sub

Sub CreateButton (EventName As String, Text As String) As B4XView
    Dim Btn As Button
    Dim FontSize As Int = 14
    #if B4i
    Btn.InitializeCustom(EventName, xui.Color_Black, xui.Color_White)
    FontSize = 16
    #else
    Btn.Initialize(EventName)
    #end if
    Dim x As B4XView =Btn
    x.SetColorAndBorder(Colors.Red,1dip,Colors.Red,40dip)
    x.Font =  xui.CreateFontAwesome(FontSize)
    'x.Color=Colors.Red
    x.TextColor=Colors.White
    x.Visible = False
    x.Text = Text
    Return x
End Sub

Private Sub B4XTable1_DataUpdated
    For i = 0 To B4XTable1.VisibleRowIds.Size -  1
        Dim p As B4XView = editCol.CellsLayouts.Get(i + 1)
        p.GetView(1).Visible = B4XTable1.VisibleRowIds.Get(i) > 0
        p.GetView(2).Visible = p.GetView(1).Visible
        p.GetView(3).Visible = p.GetView(1).Visible
    Next
    For i = 0 To B4XTable1.VisibleRowIds.Size - 1
        Dim RowId As Long = B4XTable1.VisibleRowIds.Get(i)
        Dim pnl As B4XView = signature_column.CellsLayouts.Get(i + 1) '+1 because the first cell is the header
        Dim iv As B4XView = pnl.GetView(1) 'ImageView will be the 2nd child of the panel. The built-in label is the first.
        If RowId > 0 Then
            Dim row As Map = B4XTable1.GetRow(RowId)
            Dim signature_load_file As String
            signature_load_file=row.Get("Incaricato") & "_" & row.Get("Naspo Numero") & "_" & row.Get("Data Verifica") & ".png"
            Log(signature_load_file)
            If File.Exists(File.DirInternal,signature_load_file)=True Then
                iv.setBitmap(xui.LoadBitmapResize(File.DirInternal,signature_load_file, iv.Width, iv.Height, True))
            End If
        Else
            'empty row
            iv.setBitmap(Null)
        End If
    Next
    xSelections.Refresh
End Sub

Sub B4XTable1_CellClicked (ColumnId As String, RowId As Long)
    xSelections.CellClicked(ColumnId, RowId)
    B4XRowData.Initialize
    B4XRowData= B4XTable1.GetRow(RowId)
        
End Sub
Private Sub ShowDialog(Item As Map, RowId As Long)
    DateTime.DateFormat="dd-MM-yyyy"
    
    Dim sf As Object =PrefDialog.ShowDialog(Item, "OK", "CANCELLA")
    PrefDialog.CustomListView1.AnimationDuration = 0
    For i = 0 To PrefDialog.PrefItems.Size - 1
        Dim pi As B4XPrefItem = PrefDialog.PrefItems.Get(i)
        If pi.ItemType = PrefDialog.TYPE_BOOLEAN Then
            PrefDialog.CustomListView1.ResizeItem(i, 80dip)
            Dim pnl As B4XView = PrefDialog.CustomListView1.GetPanel(i)
            pnl.Height = pnl.Parent.Height
            pnl.GetView(0).Height = pnl.Height - 20dip
            pnl.GetView(0).TextSize=12
            pnl.GetView(1).Top = 20dip
        End If
    Next
    Wait For (sf) Complete (Result As Int)
    If Result = xui.DialogResponse_Positive Then
        
        Dim params As List
        params.Initialize
        
        params.AddAll(Array(Item.Get("naspo_numero"), DateTime.Date(Item.Get("data")), Item.Get("ubicazione"), Item.Get("livello"),Item.Get("riferimenti_planimetria"),IIf(Item.Get("check1")=True,"Positivo","Negativo"),IIf(Item.Get("check2")=True,"Positivo","Negativo"),IIf(Item.Get("check3")=True,"Positivo","Negativo"),IIf(Item.Get("check4")=True,"Positivo","Negativo"),IIf(Item.Get("check5")=True,"Positivo","Negativo"),Item.Get("esito"),DateTime.Date(Item.Get("data_next")),Item.Get("incaricato"),Item.Get("qualifica"),Item.Get("responsabile"),IIf(Item.Get("firma")=Null,"",""))) 'keys based on the template json file
        If RowId = 0 Then 'new row
            B4XTable1.sql1.ExecNonQuery2($"INSERT INTO data VALUES("", ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"$, params)
            B4XTable1.Refresh
            B4XTable1.UpdateTableCounters
        Else
            params.Add(RowId)
            'first column is c0. We skip it as this is the "edit" column
            B4XTable1.sql1.ExecNonQuery2("UPDATE data SET c1 = ?, c2 = ?, c3 = ?, c4 = ?,c5 = ?,c6 = ?,c7 = ?,c8 = ?,c9 = ?,c10 = ?,c11 = ?,c12 = ?,c13 = ?,c14 = ?,c15 = ?,c16 = ? WHERE rowid = ?", params)
            B4XTable1.Refresh
            B4XTable1.UpdateTableCounters
        End If
        Log(Item)
        
        
        current_filefirma=Item.Get("Incaricato") & "_" & Item.Get("Naspo Numero") & "_" & Item.Get("Data Verifica") & ".png"
        If old_filefirma<>"" Then
            If File.Exists(File.DirInternal,old_filefirma)=True Then
                File.Delete(File.DirInternal,old_filefirma)
            End If
        End If
        Dim Dialog As B4XDialog
        Dim Base As B4XView
        Base = B4XPages.GetNativeParent(Me)
        Dialog.Initialize (Base)
        Dialog.Title = "Firma"
        Dialog.TitleBarColor=xui.Color_Red
        Dialog.TitleBarTextColor=xui.Color_White
        Dim SignatureTemplate As B4XSignatureTemplate
        SignatureTemplate.Initialize
        SignatureTemplate.AddDateAndTime=False
        Do While True
            Dim rs As ResumableSub = Dialog.ShowTemplate(SignatureTemplate, "Conferma", "","Reset")
                
            Dialog.GetButton(xui.DialogResponse_Positive).TextColor = xui.Color_Green
            Dialog.GetButton(xui.DialogResponse_Cancel).TextColor = xui.Color_Red
            Wait For (rs) Complete (Result As Int)
            If Result = xui.DialogResponse_Positive Then
                If SignatureTemplate.NumberOfPoints>0 Then
                    Dim out As OutputStream = File.OpenOutput(File.DirInternal, current_filefirma, False)
                    SignatureTemplate.Bitmap.WriteToStream(out,100,"PNG")
                    out.Close
                    Exit
                End If
            End If
        Loop
        
        ExportTableToCSV
        
    End If
    Log(data)
    
End Sub

Public Sub ExportTableToCSV
    Dim data As List
    data.Initialize
    Dim rs As ResultSet = B4XTable1.sql1.ExecQuery("SELECT * FROM data")
    Do While rs.NextRow
        Dim row(B4XTable1.Columns.Size) As String
        For i = 0 To B4XTable1.Columns.Size - 1
            Dim c As B4XTableColumn = B4XTable1.Columns.Get(i)
            row(i) = rs.GetString(c.SQLID)
        Next
        data.Add(row)
    Loop
    rs.Close
    Dim su As StringUtils
    Log(data)
    su.SaveCSV(xui.DefaultFolder, CSVFile, ",", data)
End Sub



Private Sub ExportToHtml (tbl As B4XTable) As String
Dim HtmlCSS As String = $"@page {size: legal landscape;}
        table {width: 100%;border: 1px solid #cef;text-align: center; }
        th { font-weight: bold; font-size: 12px;    background-color: #acf;    border-bottom: 1px solid #cef; }
        td { font-size: 12px; width:auto; white-space:nowrap}
        td,th {    padding: 4px 5px; }
        .odd {background-color: #def; }
        .odd td {border-bottom: 1px solid #cef; }
        a { text-decoration:none; color: #000; }"$
    Dim sb As StringBuilder
    sb.Initialize
    sb.Append("<html><body>").Append(CRLF)
    sb.Append("<style type='text/css'>").Append(HtmlCSS).Append("</style>").Append(CRLF)
    sb.Append("<table><thead><tr>").Append(CRLF)
    For Each col As B4XTableColumn In tbl.Columns
        sb.Append("<th>").Append($"$Xml{col.Title}"$).Append("</th>")
    Next
    sb.Append("</thead>")
    sb.Append("</tr>").Append(CRLF)
    Dim rs As ResultSet = tbl.sql1.ExecQuery("SELECT * FROM data")
    Dim row As Int
    Do While rs.NextRow
        If row Mod 2 = 0 Then
            sb.Append("<tr>")
        Else
            sb.Append("<tr class='odd'>")
        End If
        For i = 0 To rs.ColumnCount - 1
            sb.Append("<td>")
            sb.Append($"$Xml{rs.GetString2(i)}"$)
            sb.Append("</td>")
        Next
        sb.Append("</tr>").Append(CRLF)
        row = row + 1
    Loop
    rs.Close
    sb.Append("</table></body></html>")
    Return sb.ToString
End Sub

Private Sub html2pdf_Finished(Success As Boolean)
    Log(Success)
    If Success =True Then
        Dim in As Intent
        in.Initialize(in.ACTION_VIEW, "")
        provider.SetFileUriAsIntentData(in, "report.pdf")
        in.SetType("application/pdf")
        StartActivity(in)
    End If
End Sub

this is the log:

Logger connesso a: Xiaomi M2003J15SC
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
#SupportedOrientations attribute must be set to landscape or portrait.
*** mainpage: B4XPage_Created
*** mainpage: B4XPage_Appear
** Activity (main) Resume **
*** naspo: B4XPage_Created [mainpage]
/data/user/0/b4a.example/files
Using FileProvider? true
*** mainpage: B4XPage_Disappear [mainpage]
*** naspo: B4XPage_Appear [mainpage]
Error occurred on line: 232 (naspo)
java.lang.RuntimeException: Object should first be initialized (View).
Did you forget to call Activity.LoadLayout?
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:67)
at anywheresoftware.b4a.objects.B4XViewWrapper.GetView(B4XViewWrapper.java:320)
at b4a.example.naspo._b4xtable1_dataupdated(naspo.java:429)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:146)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1085)
at anywheresoftware.b4a.keywords.Common.CallSubNew(Common.java:1032)
at b4a.example.b4xtable$ResumableSub_ImplUpdateDataFromQuery.resume(b4xtable.java:3165)
at b4a.example.b4xtable._implupdatedatafromquery(b4xtable.java:2666)
at b4a.example.b4xtable._updatedata(b4xtable.java:2166)
at b4a.example.b4xtable._refresh2(b4xtable.java:925)
at b4a.example.b4xtable._refreshnow(b4xtable.java:3565)
at b4a.example.b4xtable$ResumableSub_SetData.resume(b4xtable.java:617)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:146)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:7864)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)

Can some one help Me ? Thanks in advances
 
Upvote 0

mike1967

Active Member
Licensed User
Longtime User
Hello, i try to implement load save and display signature (firm) in a column of a B4XTable but when run return me an error on line 232.

code:
a As Map
    Private xui As XUI
    Private editCol As B4XTableColumn
    Private const CSVFile As String = "naspi.csv"
    Dim data As List
     Private provider As FileProvider
    Private old_filefirma,current_filefirma As String =""
    Private signature_column As B4XTableColumn
   
End Sub

'You can add more parameters here.
Public Sub Initialize As Object
    B4XPages.GetManager.LogEvents = True
    Return Me
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("1")
    xui.SetDataFolder(File.DirInternal)
    Log(xui.DefaultFolder)

    editCol = B4XTable1.AddColumn("Edit", B4XTable1.COLUMN_TYPE_TEXT)
    editCol.Sortable = False
    editCol.Width = 127dip
    B4XTable1.RowHeight = 50dip
    B4XTable1.HeadersHeight =70dip
   
    B4XTable1.AddColumn("Naspo Numero", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Data Verifica", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Ubicazione", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Livello", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Riferimento Planimetria", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Naspo presente ed indicato con cartello", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Pannello frontale integro e facilmente apribile", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Etichette presenti e correttamente compilate", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Componenti integri", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Lancia presente", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Esito della Verifica", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Prossima Verifica entro il", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Incaricato", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Qualifica", B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.AddColumn("Responsabile", B4XTable1.COLUMN_TYPE_TEXT)
    signature_column=B4XTable1.AddColumn("Firma",B4XTable1.COLUMN_TYPE_TEXT)
    B4XTable1.NumberOfFrozenColumns= 1
   
    xSelections.Initialize(B4XTable1)
    xSelections.Mode = xSelections.MODE_SINGLE_LINE_PERMANENT
    xSelections.SelectionColor=xui.Color_Red     'you can change the color of the row selected with this
   
    For i = 1 To signature_column.CellsLayouts.Size - 1
        Dim pnl As B4XView = signature_column.CellsLayouts.Get(i)
        Dim iv As B4XView
        pnl.AddView(iv, 5dip, 5dip, signature_column.Width - 10dip, B4XTable1.RowHeight - 10dip)
    Next
   
    LoadData
    PrefDialog.Initialize(Root, "Schede verifiche di sorveglianza", 300dip, 300dip)
    PrefDialog.LoadFromJson(File.ReadString(File.DirAssets, "naspo.json"))
    PrefDialog.Dialog.BlurBackground=True
    PrefDialog.Dialog.PutAtTop=True
    PrefDialog.Dialog.TitleBarColor=Colors.Red
    PrefDialog.Dialog.TitleBarTextColor=Colors.White
    PrefDialog.Dialog.TitleBarHeight=130
    PrefDialog.Dialog.ButtonsColor=Colors.Red
    PrefDialog.Dialog.ButtonsTextColor=Colors.White
    PrefDialog.SearchTemplate.Resize(90%x,50%y)
    PrefDialog.SearchTemplate.SearchField.HintText="Cerca..."
    PrefDialog.SearchTemplate.SearchField.Update
    PrefDialog.SearchTemplate.MaxNumberOfItemsToShow = 300
    B4XTable1.MaximumRowsPerPage = 10
    B4XTable1.BuildLayoutsCache(B4XTable1.MaximumRowsPerPage)
    For i = 1 To editCol.CellsLayouts.Size -  1
        Dim p As B4XView = editCol.CellsLayouts.Get(i)
        p.AddView(CreateButton("btnEdit", Chr(0xF044)), 2dip, 5dip, 40dip, 40dip)
        p.AddView(CreateButton("btnDelete", Chr(0xF00D)), 44dip, 5dip, 40dip, 40dip)
        p.AddView(CreateButton("btnDuplicate",Chr(0xF0C5)), 85dip, 5dip, 40dip, 40dip)
    Next
    provider.Initialize
End Sub

Private Sub B4XPage_Background
'    'ExportTableToCSV
End Sub

Sub LoadData
   
    If File.Exists(xui.DefaultFolder, CSVFile) Then
        Dim su As StringUtils
        data = su.LoadCSV(xui.DefaultFolder, CSVFile, ",")
    Else
        data.Initialize
    End If
    B4XTable1.HeaderFont = xui.CreateDefaultBoldFont(14)
    B4XTable1.LabelsFont = xui.CreateDefaultFont(14)
    B4XTable1.SetData(data)
End Sub

Sub btnAdd_Click
    ShowDialog(CreateMap(), 0)
End Sub

Sub btnPrint_Click
    If File.Exists(provider.SharedFolder,"report.pdf")=True Then
        File.Delete(provider.SharedFolder,"report.pdf")
    End If
    Dim html2pdf As PalmoHtmlToPdf
    html2pdf.Initialize("html2pdf")
    html2pdf.ConvertFromString(ExportToHtml(B4XTable1),provider.SharedFolder,"report.pdf")
    Sleep(0)
   
   
End Sub

Sub btnDelete_Click
    Dim RowId As Long = GetRowId(Sender)
    Dim Item As Map = B4XTable1.GetRow(RowId)
    Dim sf As Object = xui.Msgbox2Async($"Cancello Naspo n.ro: ${Item.Get("Naspo Numero")}?"$, "", "Si", "", "No", Null)
    Wait For (sf) Msgbox_Result (Result As Int)
    If Result = xui.DialogResponse_Positive Then
        Dim filefirma As String
        filefirma=Item.Get("Incaricato") & "_" & Item.Get("Naspo Numero") & "_" & Item.Get("Data") & ".png"
        If File.Exists(File.DirInternal,filefirma)=True Then
            File.Delete(File.DirInternal,filefirma)
        End If
        B4XTable1.sql1.ExecNonQuery2("DELETE FROM data WHERE rowid = ?", Array(RowId))
        B4XTable1.UpdateTableCounters
       
        ExportTableToCSV
    End If
End Sub

Sub btnEdit_Click
    Dim RowId As Long = GetRowId(Sender)
    Dim Item As Map = B4XTable1.GetRow(RowId)
    old_filefirma=Item.Get("Incaricato") & "_" & Item.Get("Naspo Numero") & "_" & Item.Get("Data") & ".png"
    Dim swap As Map
    swap.Initialize
    DateTime.DateFormat="dd-MM-yyyy"
   
    swap.Put("naspo_numero",Item.Get("Naspo Numero"))
    swap.Put("data",DateTime.DateParse(Item.Get("Data Verifica")))
    swap.Put("ubicazione",Item.Get("Ubicazione"))
    swap.Put("livello",Item.Get("Livello"))
    swap.Put("riferimenti_planimetria",Item.Get("Riferimento Planimetria"))
    swap.Put("check1",IIf(Item.Get("Naspo presente ed indicato con cartello")="Positivo",True,False))
    swap.Put("check2",IIf(Item.Get("Pannello frontale integro e facilmente apribile")="Positivo",True,False))
    swap.Put("check3",IIf(Item.Get("Etichette presenti e correttamente compilate")="Positivo",True,False))
    swap.Put("check4",IIf(Item.Get("Componenti integri")="Positivo",True,False))
    swap.Put("check5",IIf(Item.Get("Lancia presente")="Positivo",True,False))
    swap.Put("esito",Item.Get("Esito della Verifica"))
    swap.Put("data_next",DateTime.DateParse(Item.Get("Prossima Verifica entro il")))
    swap.Put("incaricato",Item.Get("Incaricato"))
    swap.Put("qualifica",Item.Get("Qualifica"))
    swap.Put("responsabile",Item.Get("Responsabile"))
    swap.Put("firma",Item.Get("Firma"))
   
    ShowDialog(swap, RowId)
End Sub

Sub btnDuplicate_Click
    Dim RowId As Long = GetRowId(Sender)
    Dim Item As Map = B4XTable1.GetRow(RowId)
    Dim swap As Map
    swap.Initialize
    DateTime.DateFormat="dd-MM-yyyy"
   
    swap.Put("naspo_numero",Item.Get("Naspo Numero"))
    swap.Put("data",DateTime.DateParse(Item.Get("Data Verifica")))
    swap.Put("ubicazione",Item.Get("Ubicazione"))
    swap.Put("livello",Item.Get("Livello"))
    swap.Put("riferimenti_planimetria",Item.Get("Riferimento Planimetria"))
    swap.Put("check1",IIf(Item.Get("Naspo presente ed indicato con cartello")="Positivo",True,False))
    swap.Put("check2",IIf(Item.Get("Pannello frontale integro e facilmente apribile")="Positivo",True,False))
    swap.Put("check3",IIf(Item.Get("Etichette presenti e correttamente compilate")="Positivo",True,False))
    swap.Put("check4",IIf(Item.Get("Componenti integri")="Positivo",True,False))
    swap.Put("check5",IIf(Item.Get("Lancia presente")="Positivo",True,False))
    swap.Put("esito",Item.Get("Esito della Verifica"))
    swap.Put("data_next",DateTime.DateParse(Item.Get("Prossima Verifica entro il")))
    swap.Put("incaricato",Item.Get("Incaricato"))
    swap.Put("qualifica",Item.Get("Qualifica"))
    swap.Put("responsabile",Item.Get("Responsabile"))
    swap.Put("firma",Item.Get("Firma"))
   
    ShowDialog(swap, 0) 'RowId = 0 means that a new item will be created
End Sub

Sub GetRowId (View As B4XView) As Long
    Dim RowIndex As Int = editCol.CellsLayouts.IndexOf(View.Parent)
    Dim RowId As Long = B4XTable1.VisibleRowIds.Get(RowIndex  - 1) ' 1 because of the header
    Return RowId
End Sub

Sub CreateButton (EventName As String, Text As String) As B4XView
    Dim Btn As Button
    Dim FontSize As Int = 14
    #if B4i
    Btn.InitializeCustom(EventName, xui.Color_Black, xui.Color_White)
    FontSize = 16
    #else
    Btn.Initialize(EventName)
    #end if
    Dim x As B4XView =Btn
    x.SetColorAndBorder(Colors.Red,1dip,Colors.Red,40dip)
    x.Font =  xui.CreateFontAwesome(FontSize)
    'x.Color=Colors.Red
    x.TextColor=Colors.White
    x.Visible = False
    x.Text = Text
    Return x
End Sub

Private Sub B4XTable1_DataUpdated
    For i = 0 To B4XTable1.VisibleRowIds.Size -  1
        Dim p As B4XView = editCol.CellsLayouts.Get(i + 1)
        p.GetView(1).Visible = B4XTable1.VisibleRowIds.Get(i) > 0
        p.GetView(2).Visible = p.GetView(1).Visible
        p.GetView(3).Visible = p.GetView(1).Visible
    Next
    For i = 0 To B4XTable1.VisibleRowIds.Size - 1
        Dim RowId As Long = B4XTable1.VisibleRowIds.Get(i)
        Dim pnl As B4XView = signature_column.CellsLayouts.Get(i + 1) '+1 because the first cell is the header
        Dim iv As B4XView = pnl.GetView(1) 'ImageView will be the 2nd child of the panel. The built-in label is the first.
        If RowId > 0 Then
            Dim row As Map = B4XTable1.GetRow(RowId)
            Dim signature_load_file As String
            signature_load_file=row.Get("Incaricato") & "_" & row.Get("Naspo Numero") & "_" & row.Get("Data Verifica") & ".png"
            Log(signature_load_file)
            If File.Exists(File.DirInternal,signature_load_file)=True Then
                iv.setBitmap(xui.LoadBitmapResize(File.DirInternal,signature_load_file, iv.Width, iv.Height, True))
            End If
        Else
            'empty row
            iv.setBitmap(Null)
        End If
    Next
    xSelections.Refresh
End Sub

Sub B4XTable1_CellClicked (ColumnId As String, RowId As Long)
    xSelections.CellClicked(ColumnId, RowId)
    B4XRowData.Initialize
    B4XRowData= B4XTable1.GetRow(RowId)
       
End Sub
Private Sub ShowDialog(Item As Map, RowId As Long)
    DateTime.DateFormat="dd-MM-yyyy"
   
    Dim sf As Object =PrefDialog.ShowDialog(Item, "OK", "CANCELLA")
    PrefDialog.CustomListView1.AnimationDuration = 0
    For i = 0 To PrefDialog.PrefItems.Size - 1
        Dim pi As B4XPrefItem = PrefDialog.PrefItems.Get(i)
        If pi.ItemType = PrefDialog.TYPE_BOOLEAN Then
            PrefDialog.CustomListView1.ResizeItem(i, 80dip)
            Dim pnl As B4XView = PrefDialog.CustomListView1.GetPanel(i)
            pnl.Height = pnl.Parent.Height
            pnl.GetView(0).Height = pnl.Height - 20dip
            pnl.GetView(0).TextSize=12
            pnl.GetView(1).Top = 20dip
        End If
    Next
    Wait For (sf) Complete (Result As Int)
    If Result = xui.DialogResponse_Positive Then
       
        Dim params As List
        params.Initialize
       
        params.AddAll(Array(Item.Get("naspo_numero"), DateTime.Date(Item.Get("data")), Item.Get("ubicazione"), Item.Get("livello"),Item.Get("riferimenti_planimetria"),IIf(Item.Get("check1")=True,"Positivo","Negativo"),IIf(Item.Get("check2")=True,"Positivo","Negativo"),IIf(Item.Get("check3")=True,"Positivo","Negativo"),IIf(Item.Get("check4")=True,"Positivo","Negativo"),IIf(Item.Get("check5")=True,"Positivo","Negativo"),Item.Get("esito"),DateTime.Date(Item.Get("data_next")),Item.Get("incaricato"),Item.Get("qualifica"),Item.Get("responsabile"),IIf(Item.Get("firma")=Null,"",""))) 'keys based on the template json file
        If RowId = 0 Then 'new row
            B4XTable1.sql1.ExecNonQuery2($"INSERT INTO data VALUES("", ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"$, params)
            B4XTable1.Refresh
            B4XTable1.UpdateTableCounters
        Else
            params.Add(RowId)
            'first column is c0. We skip it as this is the "edit" column
            B4XTable1.sql1.ExecNonQuery2("UPDATE data SET c1 = ?, c2 = ?, c3 = ?, c4 = ?,c5 = ?,c6 = ?,c7 = ?,c8 = ?,c9 = ?,c10 = ?,c11 = ?,c12 = ?,c13 = ?,c14 = ?,c15 = ?,c16 = ? WHERE rowid = ?", params)
            B4XTable1.Refresh
            B4XTable1.UpdateTableCounters
        End If
        Log(Item)
       
       
        current_filefirma=Item.Get("Incaricato") & "_" & Item.Get("Naspo Numero") & "_" & Item.Get("Data Verifica") & ".png"
        If old_filefirma<>"" Then
            If File.Exists(File.DirInternal,old_filefirma)=True Then
                File.Delete(File.DirInternal,old_filefirma)
            End If
        End If
        Dim Dialog As B4XDialog
        Dim Base As B4XView
        Base = B4XPages.GetNativeParent(Me)
        Dialog.Initialize (Base)
        Dialog.Title = "Firma"
        Dialog.TitleBarColor=xui.Color_Red
        Dialog.TitleBarTextColor=xui.Color_White
        Dim SignatureTemplate As B4XSignatureTemplate
        SignatureTemplate.Initialize
        SignatureTemplate.AddDateAndTime=False
        Do While True
            Dim rs As ResumableSub = Dialog.ShowTemplate(SignatureTemplate, "Conferma", "","Reset")
               
            Dialog.GetButton(xui.DialogResponse_Positive).TextColor = xui.Color_Green
            Dialog.GetButton(xui.DialogResponse_Cancel).TextColor = xui.Color_Red
            Wait For (rs) Complete (Result As Int)
            If Result = xui.DialogResponse_Positive Then
                If SignatureTemplate.NumberOfPoints>0 Then
                    Dim out As OutputStream = File.OpenOutput(File.DirInternal, current_filefirma, False)
                    SignatureTemplate.Bitmap.WriteToStream(out,100,"PNG")
                    out.Close
                    Exit
                End If
            End If
        Loop
       
        ExportTableToCSV
       
    End If
    Log(data)
   
End Sub

Public Sub ExportTableToCSV
    Dim data As List
    data.Initialize
    Dim rs As ResultSet = B4XTable1.sql1.ExecQuery("SELECT * FROM data")
    Do While rs.NextRow
        Dim row(B4XTable1.Columns.Size) As String
        For i = 0 To B4XTable1.Columns.Size - 1
            Dim c As B4XTableColumn = B4XTable1.Columns.Get(i)
            row(i) = rs.GetString(c.SQLID)
        Next
        data.Add(row)
    Loop
    rs.Close
    Dim su As StringUtils
    Log(data)
    su.SaveCSV(xui.DefaultFolder, CSVFile, ",", data)
End Sub



Private Sub ExportToHtml (tbl As B4XTable) As String
Dim HtmlCSS As String = $"@page {size: legal landscape;}
        table {width: 100%;border: 1px solid #cef;text-align: center; }
        th { font-weight: bold; font-size: 12px;    background-color: #acf;    border-bottom: 1px solid #cef; }
        td { font-size: 12px; width:auto; white-space:nowrap}
        td,th {    padding: 4px 5px; }
        .odd {background-color: #def; }
        .odd td {border-bottom: 1px solid #cef; }
        a { text-decoration:none; color: #000; }"$
    Dim sb As StringBuilder
    sb.Initialize
    sb.Append("<html><body>").Append(CRLF)
    sb.Append("<style type='text/css'>").Append(HtmlCSS).Append("</style>").Append(CRLF)
    sb.Append("<table><thead><tr>").Append(CRLF)
    For Each col As B4XTableColumn In tbl.Columns
        sb.Append("<th>").Append($"$Xml{col.Title}"$).Append("</th>")
    Next
    sb.Append("</thead>")
    sb.Append("</tr>").Append(CRLF)
    Dim rs As ResultSet = tbl.sql1.ExecQuery("SELECT * FROM data")
    Dim row As Int
    Do While rs.NextRow
        If row Mod 2 = 0 Then
            sb.Append("<tr>")
        Else
            sb.Append("<tr class='odd'>")
        End If
        For i = 0 To rs.ColumnCount - 1
            sb.Append("<td>")
            sb.Append($"$Xml{rs.GetString2(i)}"$)
            sb.Append("</td>")
        Next
        sb.Append("</tr>").Append(CRLF)
        row = row + 1
    Loop
    rs.Close
    sb.Append("</table></body></html>")
    Return sb.ToString
End Sub

Private Sub html2pdf_Finished(Success As Boolean)
    Log(Success)
    If Success =True Then
        Dim in As Intent
        in.Initialize(in.ACTION_VIEW, "")
        provider.SetFileUriAsIntentData(in, "report.pdf")
        in.SetType("application/pdf")
        StartActivity(in)
    End If
End Sub

this is the log:

Logger connesso a: Xiaomi M2003J15SC
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
#SupportedOrientations attribute must be set to landscape or portrait.
*** mainpage: B4XPage_Created
*** mainpage: B4XPage_Appear
** Activity (main) Resume **
*** naspo: B4XPage_Created [mainpage]
/data/user/0/b4a.example/files
Using FileProvider? true
*** mainpage: B4XPage_Disappear [mainpage]
*** naspo: B4XPage_Appear [mainpage]
Error occurred on line: 232 (naspo)
java.lang.RuntimeException: Object should first be initialized (View).
Did you forget to call Activity.LoadLayout?
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:67)
at anywheresoftware.b4a.objects.B4XViewWrapper.GetView(B4XViewWrapper.java:320)
at b4a.example.naspo._b4xtable1_dataupdated(naspo.java:429)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:146)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1085)
at anywheresoftware.b4a.keywords.Common.CallSubNew(Common.java:1032)
at b4a.example.b4xtable$ResumableSub_ImplUpdateDataFromQuery.resume(b4xtable.java:3165)
at b4a.example.b4xtable._implupdatedatafromquery(b4xtable.java:2666)
at b4a.example.b4xtable._updatedata(b4xtable.java:2166)
at b4a.example.b4xtable._refresh2(b4xtable.java:925)
at b4a.example.b4xtable._refreshnow(b4xtable.java:3565)
at b4a.example.b4xtable$ResumableSub_SetData.resume(b4xtable.java:617)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:146)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:7864)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)

Can some one help Me ? Thanks in advances
code:
Dim iv As B4XView = pnl.GetView(1)
line of error
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
It's a lot easier if you add an export as zip file of your program.
 
Upvote 0

mike1967

Active Member
Licensed User
Longtime User
Hello, i was able to add signature (firm) to a column of B4XTable with this code :
code:
Private Sub B4XTable1_DataUpdated
    For i = 0 To B4XTable1.VisibleRowIds.Size -  1
        Dim p As B4XView = editCol.CellsLayouts.Get(i + 1)
        p.GetView(1).Visible = B4XTable1.VisibleRowIds.Get(i) > 0
        p.GetView(2).Visible = p.GetView(1).Visible
        p.GetView(3).Visible = p.GetView(1).Visible
    Next
    For i = 1 To B4XTable1.Size
            Dim row As Map =B4XTable1.GetRow(i)
            Dim d As String=row.Get("Data Verifica")
            d=d.Replace("-","")
            Dim filefirma As String=row.Get("Incaricato") & row.Get("Naspo Numero") & d & ".png"  
            Log(filefirma)
            If File.Exists(File.DirInternal,filefirma)=True Then
            Dim pnl As B4XView = signature_column.CellsLayouts.Get(i)
            Dim iv As ImageView
            iv.Initialize("")
            Dim bmp As Bitmap =LoadBitmapResize(File.DirInternal,filefirma,signature_column.Width-10dip,B4XTable1.RowHeight-10dip,True)
            bmp=effect.ReplaceColor(bmp,Colors.LightGray,Colors.Transparent)
            iv.Bitmap=bmp
            pnl.AddView(iv, 5dip, 5dip, signature_column.Width - 10dip, B4XTable1.RowHeight - 10dip)
            End If  
    Next
   
    xSelections.Refresh
End Sub
but when i modify then signature (eg new or update) i have multiple imageview added to panel of cell of signaturecolumn. How i can remove the old ImageView view and replace it with its update ? Thanks in advanced
 

Attachments

  • WhatsApp Image 2022-09-21 at 19.05.31.jpeg
    WhatsApp Image 2022-09-21 at 19.05.31.jpeg
    83.1 KB · Views: 85
Upvote 0

mike1967

Active Member
Licensed User
Longtime User
You shouldn't add views in DataUpdated event.
Add the views once after you call B4XTable.BuildLayoutsCache. Only change the image in DataUpdated.
I have do this:
Save Signature:
Do While True
            Dim rs As ResumableSub = Dialog.ShowTemplate(SignatureTemplate, "Conferma", "","Reset")
               
            Dialog.GetButton(xui.DialogResponse_Positive).TextColor = xui.Color_Green
            Dialog.GetButton(xui.DialogResponse_Cancel).TextColor = xui.Color_Red
            Wait For (rs) Complete (Result As Int)
            If Result = xui.DialogResponse_Positive Then
                If SignatureTemplate.NumberOfPoints>0 Then
                    Dim out As OutputStream = File.OpenOutput(File.DirInternal, "signature.png", False)
                    SignatureTemplate.Bitmap.WriteToStream(out,100,"PNG")
                    out.Close
                    Exit
                End If
            End If
        Loop
        Dim bmp As Bitmap=LoadBitmapResize(File.DirInternal,"signature.png",signature_column.Width-10dip,B4XTable1.RowHeight-10dip,True)
        Dim base64signature As String=Base64EncodeDecodeImage.Base64ImageToString2(bmp)
        Log(base64signature.Length)

        Dim params As List
        params.Initialize
       
        params.AddAll(Array(Item.Get("naspo_numero"), DateTime.Date(Item.Get("data")), Item.Get("ubicazione"), Item.Get("livello"),Item.Get("riferimenti_planimetria"),IIf(Item.Get("check1")=True,"Positivo","Negativo"),IIf(Item.Get("check2")=True,"Positivo","Negativo"),IIf(Item.Get("check3")=True,"Positivo","Negativo"),IIf(Item.Get("check4")=True,"Positivo","Negativo"),IIf(Item.Get("check5")=True,"Positivo","Negativo"),Item.Get("esito"),DateTime.Date(Item.Get("data_next")),Item.Get("incaricato"),Item.Get("qualifica"),Item.Get("responsabile"),base64signature)) 'keys based on the template json file
        'Dim d As String=DateTime.Date(Item.Get("data"))
        'd=d.Replace("-","")
        'filefirma=Item.Get("incaricato") & Item.Get("naspo_numero") & d & ".png"
        If RowId = 0 Then 'new row
            B4XTable1.sql1.ExecNonQuery2($"INSERT INTO data VALUES("", ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"$, params)
            B4XTable1.Refresh
            B4XTable1.UpdateTableCounters
        Else
            params.Add(RowId)
           
            'first column is c0. We skip it as this is the "edit" column
            B4XTable1.sql1.ExecNonQuery2("UPDATE data SET c1 = ?, c2 = ?, c3 = ?, c4 = ?,c5 = ?,c6 = ?,c7 = ?,c8 = ?,c9 = ?,c10 = ?,c11 = ?,c12 = ?,c13 = ?,c14 = ?,c15 = ?,c16 = ? WHERE rowid = ?", params)
        '    Dim p As B4XView = signature_column.CellsLayouts.Get(RowId)
        '    If p.GetView(1).Tag<>"" Or p.GetView(1).Tag<>Null Then
        '        If File.Exists(File.DirInternal,p.GetView(1).Tag)=True Then
        '            Log("deletefile")
        '            Log(p.GetView(1).Tag)
        '            File.Delete(File.DirInternal,p.GetView(1).Tag)
        '        End If
        '    End If
            B4XTable1.Refresh
            B4XTable1.UpdateTableCounters
        End If

Add Image View to B4XTAble:
For i = 1 To signature_column.CellsLayouts.Size -  1
        Dim p As B4XView =signature_column.CellsLayouts.Get(i)
        Dim iv As ImageView
        iv.Initialize("")
        p.AddView(iv, 5dip, 5dip, signature_column.Width - 10dip, B4XTable1.RowHeight - 10dip)
    Next

Update Signature:
Private Sub B4XTable1_DataUpdated
    For i = 0 To B4XTable1.VisibleRowIds.Size -  1
        Dim p As B4XView = editCol.CellsLayouts.Get(i + 1)
        p.GetView(1).Visible = B4XTable1.VisibleRowIds.Get(i) > 0
        p.GetView(2).Visible = p.GetView(1).Visible
        p.GetView(3).Visible = p.GetView(1).Visible
    Next
    For i = 0 To B4XTable1.VisibleRowIds.Size -  1
        Dim p As B4XView = signature_column.CellsLayouts.Get(i+1)
        If B4XTable1.VisibleRowIds.Get(i) >0 Then
            p.GetView(0).Visible=False
            Log(p.GetView(0).Text)
            Dim bmp As Bitmap=Base64EncodeDecodeImage.Base64StringToImage(p.GetView(0).Text)
            bmp=effect.ReplaceColor(bmp,Colors.LightGray,Colors.Transparent)
            p.GetView(1).SetBitmap(bmp)
        End If
    Next
       
    xSelections.Refresh
End Sub

Now i retrieve the Signature Images like in attachement with a fixed Line.
How Avoid This ?
Is this way correct consider the aument of size of the file csv wher to save the data of B4XTable (is correct maximum 4GByte?)
Thanks in advances
 

Attachments

  • WhatsApp Image 2022-09-22 at 16.55.26.jpeg
    WhatsApp Image 2022-09-22 at 16.55.26.jpeg
    91.2 KB · Views: 67
Last edited:
Upvote 0

mike1967

Active Member
Licensed User
Longtime User
I have do this:
Save Signature:
Do While True
            Dim rs As ResumableSub = Dialog.ShowTemplate(SignatureTemplate, "Conferma", "","Reset")
              
            Dialog.GetButton(xui.DialogResponse_Positive).TextColor = xui.Color_Green
            Dialog.GetButton(xui.DialogResponse_Cancel).TextColor = xui.Color_Red
            Wait For (rs) Complete (Result As Int)
            If Result = xui.DialogResponse_Positive Then
                If SignatureTemplate.NumberOfPoints>0 Then
                    Dim out As OutputStream = File.OpenOutput(File.DirInternal, "signature.png", False)
                    SignatureTemplate.Bitmap.WriteToStream(out,100,"PNG")
                    out.Close
                    Exit
                End If
            End If
        Loop
        Dim bmp As Bitmap=LoadBitmapResize(File.DirInternal,"signature.png",signature_column.Width-10dip,B4XTable1.RowHeight-10dip,True)
        Dim base64signature As String=Base64EncodeDecodeImage.Base64ImageToString2(bmp)
        Log(base64signature.Length)

        Dim params As List
        params.Initialize
      
        params.AddAll(Array(Item.Get("naspo_numero"), DateTime.Date(Item.Get("data")), Item.Get("ubicazione"), Item.Get("livello"),Item.Get("riferimenti_planimetria"),IIf(Item.Get("check1")=True,"Positivo","Negativo"),IIf(Item.Get("check2")=True,"Positivo","Negativo"),IIf(Item.Get("check3")=True,"Positivo","Negativo"),IIf(Item.Get("check4")=True,"Positivo","Negativo"),IIf(Item.Get("check5")=True,"Positivo","Negativo"),Item.Get("esito"),DateTime.Date(Item.Get("data_next")),Item.Get("incaricato"),Item.Get("qualifica"),Item.Get("responsabile"),base64signature)) 'keys based on the template json file
        'Dim d As String=DateTime.Date(Item.Get("data"))
        'd=d.Replace("-","")
        'filefirma=Item.Get("incaricato") & Item.Get("naspo_numero") & d & ".png"
        If RowId = 0 Then 'new row
            B4XTable1.sql1.ExecNonQuery2($"INSERT INTO data VALUES("", ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"$, params)
            B4XTable1.Refresh
            B4XTable1.UpdateTableCounters
        Else
            params.Add(RowId)
          
            'first column is c0. We skip it as this is the "edit" column
            B4XTable1.sql1.ExecNonQuery2("UPDATE data SET c1 = ?, c2 = ?, c3 = ?, c4 = ?,c5 = ?,c6 = ?,c7 = ?,c8 = ?,c9 = ?,c10 = ?,c11 = ?,c12 = ?,c13 = ?,c14 = ?,c15 = ?,c16 = ? WHERE rowid = ?", params)
        '    Dim p As B4XView = signature_column.CellsLayouts.Get(RowId)
        '    If p.GetView(1).Tag<>"" Or p.GetView(1).Tag<>Null Then
        '        If File.Exists(File.DirInternal,p.GetView(1).Tag)=True Then
        '            Log("deletefile")
        '            Log(p.GetView(1).Tag)
        '            File.Delete(File.DirInternal,p.GetView(1).Tag)
        '        End If
        '    End If
            B4XTable1.Refresh
            B4XTable1.UpdateTableCounters
        End If

Add Image View to B4XTAble:
For i = 1 To signature_column.CellsLayouts.Size -  1
        Dim p As B4XView =signature_column.CellsLayouts.Get(i)
        Dim iv As ImageView
        iv.Initialize("")
        p.AddView(iv, 5dip, 5dip, signature_column.Width - 10dip, B4XTable1.RowHeight - 10dip)
    Next

Update Signature:
Private Sub B4XTable1_DataUpdated
    For i = 0 To B4XTable1.VisibleRowIds.Size -  1
        Dim p As B4XView = editCol.CellsLayouts.Get(i + 1)
        p.GetView(1).Visible = B4XTable1.VisibleRowIds.Get(i) > 0
        p.GetView(2).Visible = p.GetView(1).Visible
        p.GetView(3).Visible = p.GetView(1).Visible
    Next
    For i = 0 To B4XTable1.VisibleRowIds.Size -  1
        Dim p As B4XView = signature_column.CellsLayouts.Get(i+1)
        If B4XTable1.VisibleRowIds.Get(i) >0 Then
            p.GetView(0).Visible=False
            Log(p.GetView(0).Text)
            Dim bmp As Bitmap=Base64EncodeDecodeImage.Base64StringToImage(p.GetView(0).Text)
            bmp=effect.ReplaceColor(bmp,Colors.LightGray,Colors.Transparent)
            p.GetView(1).SetBitmap(bmp)
        End If
    Next
      
    xSelections.Refresh
End Sub

Now i retrieve the Signature Images like in attachement with a fixed Line.
How Avoid This ?
Is this way correct consider the aument of size of the file csv wher to save the data of B4XTable (is correct maximum 4GByte?)
Thanks in advances
Solved for the fixed line use the alternate library of https://www.b4x.com/android/forum/t...ode-image-and-file-library.115033/post-736584
Save Signature:
Dim bmp As Bitmap=LoadBitmapResize(File.DirInternal,"signature.png",signature_column.Width-10dip,B4XTable1.RowHeight-10dip,True)
        'Dim base64signature As String=Base64EncodeDecodeImage.Base64ImageToString2(bmp)
        Dim base64signature As String=Base64EncodeDecodeImage.ImageToString2(bmp)
 
Upvote 0
Top