diff --git a/TrasferimentoProgrammiOkuma.App/Form1.vb b/TrasferimentoProgrammiOkuma.App/Form1.vb index c294715..cbef23c 100644 --- a/TrasferimentoProgrammiOkuma.App/Form1.vb +++ b/TrasferimentoProgrammiOkuma.App/Form1.vb @@ -42,6 +42,13 @@ Public Class Form1 Private ReadOnly nudIntervalloStatoMoxa As New NumericUpDown() Private ReadOnly lstStatoMoxa As New ListView() Private ReadOnly imgStatoMoxa As New ImageList() + Private ReadOnly txtFileModifica As New TextBox() + Private ReadOnly txtNomeFileModifica As New TextBox() + Private ReadOnly btnSfogliaModifica As New Button() + Private ReadOnly btnRendiMaiuscolo As New Button() + Private ReadOnly btnAggiungiElementiOkuma As New Button() + Private ReadOnly btnSalvaModifica As New Button() + Private ReadOnly rtbEditorModifica As New RichTextBox() Private ReadOnly statusTimer As New System.Windows.Forms.Timer() Private ReadOnly txtLog As New TextBox() Private ReadOnly progress As New ProgressBar() @@ -52,6 +59,7 @@ Public Class Form1 Private controlsUnlocked As Boolean Private loadingSelection As Boolean Private checkingMoxaStatus As Boolean + Private currentEditDirectory As String = "" Public Sub New() InitializeComponent() @@ -87,8 +95,10 @@ Public Class Form1 Dim tabs As New TabControl With {.Dock = DockStyle.Fill, .Margin = Padding.Empty} Dim tabTrasferimento As New TabPage("Trasferimento programmi") + Dim tabModificaFile As New TabPage("Modifica file") Dim tabStatoMoxa As New TabPage("Stato Moxa") tabs.TabPages.Add(tabTrasferimento) + tabs.TabPages.Add(tabModificaFile) tabs.TabPages.Add(tabStatoMoxa) shell.Controls.Add(tabs, 0, 1) @@ -253,6 +263,7 @@ Public Class Form1 AddHandler btnAnnulla.Click, Sub() cts?.Cancel() txtFileRicezione.Text = GetInitialReceiveDirectory() + BuildEditFileTab(tabModificaFile) BuildStatusTab(tabStatoMoxa) Log($"Pronto. Configurazione: {ConfigPath()}") End Sub @@ -281,6 +292,232 @@ Public Class Form1 Return Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) End Function + Private Sub BuildEditFileTab(tab As TabPage) + Dim root As New TableLayoutPanel With { + .Dock = DockStyle.Fill, + .ColumnCount = 1, + .RowCount = 3, + .Padding = New Padding(14) + } + root.RowStyles.Add(New RowStyle(SizeType.AutoSize)) + root.RowStyles.Add(New RowStyle(SizeType.Percent, 100)) + root.RowStyles.Add(New RowStyle(SizeType.AutoSize)) + tab.Controls.Add(root) + + Dim selectors As New TableLayoutPanel With {.Dock = DockStyle.Top, .ColumnCount = 4, .RowCount = 2, .AutoSize = True} + selectors.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize)) + selectors.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100)) + selectors.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize)) + selectors.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 150)) + root.Controls.Add(selectors, 0, 0) + + ConfigureButton(btnSfogliaModifica, "Sfoglia") + ConfigureButton(btnRendiMaiuscolo, "Rendi Maiuscolo") + ConfigureButton(btnAggiungiElementiOkuma, "Aggiungi elementi Necessari") + ConfigureButton(btnSalvaModifica, "Salva") + txtFileModifica.Dock = DockStyle.Fill + txtFileModifica.ReadOnly = True + txtNomeFileModifica.Dock = DockStyle.Fill + + selectors.Controls.Add(New Label With {.Text = "File", .AutoSize = True, .Anchor = AnchorStyles.Left}, 0, 0) + selectors.Controls.Add(txtFileModifica, 1, 0) + selectors.Controls.Add(btnSfogliaModifica, 2, 0) + selectors.Controls.Add(New Label With {.Text = "Nome salvataggio", .AutoSize = True, .Anchor = AnchorStyles.Left, .Margin = New Padding(0, 8, 3, 0)}, 0, 1) + selectors.Controls.Add(txtNomeFileModifica, 1, 1) + + rtbEditorModifica.Dock = DockStyle.Fill + rtbEditorModifica.Font = New Font("Consolas", 10.0F) + rtbEditorModifica.WordWrap = False + rtbEditorModifica.AcceptsTab = True + rtbEditorModifica.ScrollBars = RichTextBoxScrollBars.Both + rtbEditorModifica.DetectUrls = False + rtbEditorModifica.HideSelection = False + rtbEditorModifica.Margin = New Padding(0, 12, 0, 12) + root.Controls.Add(rtbEditorModifica, 0, 1) + + Dim actions As New FlowLayoutPanel With {.Dock = DockStyle.Fill, .AutoSize = True, .FlowDirection = FlowDirection.LeftToRight} + actions.Controls.Add(btnRendiMaiuscolo) + actions.Controls.Add(btnAggiungiElementiOkuma) + actions.Controls.Add(btnSalvaModifica) + root.Controls.Add(actions, 0, 2) + + AddHandler btnSfogliaModifica.Click, AddressOf SelectEditFile + AddHandler btnRendiMaiuscolo.Click, AddressOf UppercaseEditFile + AddHandler btnAggiungiElementiOkuma.Click, AddressOf AddOkumaElements + AddHandler btnSalvaModifica.Click, AddressOf SaveEditedFile + End Sub + + Private Sub SelectEditFile(sender As Object, e As EventArgs) + Using dialog As New OpenFileDialog With { + .Title = "Seleziona file da modificare", + .Filter = "Tutti i file (*.*)|*.*", + .CheckFileExists = True + } + If Directory.Exists(currentEditDirectory) Then + dialog.InitialDirectory = currentEditDirectory + Else + dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + End If + + If dialog.ShowDialog(Me) <> DialogResult.OK Then + Return + End If + + Dim bytes = File.ReadAllBytes(dialog.FileName) + Dim content = Encoding.Latin1.GetString(bytes) + txtFileModifica.Text = dialog.FileName + txtNomeFileModifica.Text = Path.GetFileName(dialog.FileName) + currentEditDirectory = Path.GetDirectoryName(dialog.FileName) + rtbEditorModifica.Text = ToVisibleControlText(content) + Log($"File caricato per modifica: {dialog.FileName}") + End Using + End Sub + + Private Sub UppercaseEditFile(sender As Object, e As EventArgs) + rtbEditorModifica.Text = rtbEditorModifica.Text.ToUpperInvariant() + End Sub + + Private Sub AddOkumaElements(sender As Object, e As EventArgs) + Dim fileName = txtNomeFileModifica.Text.Trim() + If String.IsNullOrWhiteSpace(fileName) Then + MessageBox.Show(Me, "Inserire il nome del file da usare nell'intestazione Okuma.", "Modifica file", MessageBoxButtons.OK, MessageBoxIcon.Warning) + Return + End If + + Dim content = FromVisibleControlText(rtbEditorModifica.Text) + Dim header = ChrW(&H12) & " $" & fileName & " %" & vbCrLf + Dim footer = "%" & vbCrLf & ChrW(&H14) + + If Not content.StartsWith(ChrW(&H12), StringComparison.Ordinal) Then + content = header & content + End If + + If Not EndsWithOkumaFooter(content) Then + If content.Length > 0 AndAlso Not content.EndsWith(vbCrLf, StringComparison.Ordinal) Then + content &= vbCrLf + End If + content &= footer + End If + + rtbEditorModifica.Text = ToVisibleControlText(content) + End Sub + + Private Sub SaveEditedFile(sender As Object, e As EventArgs) + Dim fileName = txtNomeFileModifica.Text.Trim() + If String.IsNullOrWhiteSpace(fileName) OrElse fileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0 Then + MessageBox.Show(Me, "Inserire un nome file valido.", "Salva file", MessageBoxButtons.OK, MessageBoxIcon.Warning) + Return + End If + + Using dialog As New SaveFileDialog With { + .Title = "Salva file modificato", + .Filter = "Tutti i file (*.*)|*.*", + .FileName = fileName, + .OverwritePrompt = True + } + If Directory.Exists(currentEditDirectory) Then + dialog.InitialDirectory = currentEditDirectory + ElseIf Not String.IsNullOrWhiteSpace(txtFileModifica.Text) AndAlso Directory.Exists(Path.GetDirectoryName(txtFileModifica.Text)) Then + dialog.InitialDirectory = Path.GetDirectoryName(txtFileModifica.Text) + Else + dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + End If + + If dialog.ShowDialog(Me) <> DialogResult.OK Then + Return + End If + + Dim content = FromVisibleControlText(rtbEditorModifica.Text) + File.WriteAllBytes(dialog.FileName, Encoding.Latin1.GetBytes(content)) + currentEditDirectory = Path.GetDirectoryName(dialog.FileName) + txtFileModifica.Text = dialog.FileName + txtNomeFileModifica.Text = Path.GetFileName(dialog.FileName) + Log($"File modificato salvato: {dialog.FileName}") + End Using + End Sub + + Private Shared Function EndsWithOkumaFooter(content As String) As Boolean + Dim trimmed = content.TrimEnd(ControlChars.Cr, ControlChars.Lf, ControlChars.NullChar, " "c, ControlChars.Tab) + Return trimmed.EndsWith(ChrW(&H14), StringComparison.Ordinal) + End Function + + Private Shared Function ToVisibleControlText(content As String) As String + Dim builder As New StringBuilder(content.Length) + For Each ch In content + Select Case AscW(ch) + Case &H0 + builder.Append("[NUL]") + Case &HA + builder.Append("[LF]") + Case &HD + builder.Append("[CR]") + Case &H12 + builder.Append("[DC2]") + Case &H14 + builder.Append("[DC4]") + Case 1 To 8, 11, 12, 14 To 17, 19, 21 To 31 + builder.Append($"[0x{AscW(ch):X2}]") + Case Else + builder.Append(ch) + End Select + Next + Return builder.ToString() + End Function + + Private Shared Function FromVisibleControlText(visibleText As String) As String + Dim builder As New StringBuilder(visibleText.Length) + Dim i = 0 + While i < visibleText.Length + If visibleText(i) = "["c Then + Dim closeIndex = visibleText.IndexOf("]"c, i + 1) + If closeIndex > i Then + Dim token = visibleText.Substring(i + 1, closeIndex - i - 1) + Dim controlChar As Char + If TryParseControlToken(token, controlChar) Then + builder.Append(controlChar) + i = closeIndex + 1 + Continue While + End If + End If + End If + + builder.Append(visibleText(i)) + i += 1 + End While + Return builder.ToString() + End Function + + Private Shared Function TryParseControlToken(token As String, ByRef controlChar As Char) As Boolean + Select Case token.Trim().ToUpperInvariant() + Case "NUL" + controlChar = ChrW(&H0) + Return True + Case "LF" + controlChar = ControlChars.Lf + Return True + Case "CR" + controlChar = ControlChars.Cr + Return True + Case "DC2" + controlChar = ChrW(&H12) + Return True + Case "DC4" + controlChar = ChrW(&H14) + Return True + End Select + + If token.StartsWith("0x", StringComparison.OrdinalIgnoreCase) Then + Dim value As Integer + If Integer.TryParse(token.Substring(2), Globalization.NumberStyles.HexNumber, Globalization.CultureInfo.InvariantCulture, value) AndAlso value >= 0 AndAlso value <= 31 Then + controlChar = ChrW(value) + Return True + End If + End If + + controlChar = ControlChars.NullChar + Return False + End Function + Private Sub BuildStatusTab(tab As TabPage) Dim root As New TableLayoutPanel With { .Dock = DockStyle.Fill, diff --git a/TrasferimentoProgrammiOkuma.App/Properties/PublishProfiles/GiteaClickOnce.pubxml b/TrasferimentoProgrammiOkuma.App/Properties/PublishProfiles/GiteaClickOnce.pubxml index a8c12b0..56f1fba 100644 --- a/TrasferimentoProgrammiOkuma.App/Properties/PublishProfiles/GiteaClickOnce.pubxml +++ b/TrasferimentoProgrammiOkuma.App/Properties/PublishProfiles/GiteaClickOnce.pubxml @@ -16,9 +16,9 @@ LMEMoxaTransfer Compomac SPA Compomac SPA - 1.0.5.0 + 1.0.6.0 true - 1.0.5.0 + 1.0.6.0 true false true diff --git a/TrasferimentoProgrammiOkuma.App/TrasferimentoProgrammiOkuma.App.vbproj b/TrasferimentoProgrammiOkuma.App/TrasferimentoProgrammiOkuma.App.vbproj index 9257b41..3335767 100644 --- a/TrasferimentoProgrammiOkuma.App/TrasferimentoProgrammiOkuma.App.vbproj +++ b/TrasferimentoProgrammiOkuma.App/TrasferimentoProgrammiOkuma.App.vbproj @@ -9,7 +9,7 @@ LMEMoxaTransfer Compomac SPA Livio Merola - 1.0.5.0 + 1.0.6.0 Assets\app-icon.ico Sub Main true diff --git a/clickonce/LMEMoxaTransfer.application b/clickonce/LMEMoxaTransfer.application index bb50b25..c797a9a 100644 --- a/clickonce/LMEMoxaTransfer.application +++ b/clickonce/LMEMoxaTransfer.application @@ -1,8 +1,8 @@  - + - + @@ -15,13 +15,13 @@ - + - LUY2ptxSFoDL+WjYOi2LPVBg/PGNJN8aZ3otAyFtETI= + mJjUvvN5hw6/tcW5g2EyJiI9EO8sPmyPuPztuzjUPCY= diff --git a/clickonce/LMEMoxaTransfer.deps.json b/clickonce/LMEMoxaTransfer.deps.json index ed90acd..298ca6b 100644 --- a/clickonce/LMEMoxaTransfer.deps.json +++ b/clickonce/LMEMoxaTransfer.deps.json @@ -7,7 +7,7 @@ "targets": { ".NETCoreApp,Version=v8.0": {}, ".NETCoreApp,Version=v8.0/win-x64": { - "LMEMoxaTransfer/1.0.5.0": { + "LMEMoxaTransfer/1.0.6.0": { "dependencies": { "runtimepack.Microsoft.NETCore.App.Runtime.win-x64": "8.0.29", "runtimepack.Microsoft.WindowsDesktop.App.Runtime.win-x64": "8.0.29" @@ -964,7 +964,7 @@ } }, "libraries": { - "LMEMoxaTransfer/1.0.5.0": { + "LMEMoxaTransfer/1.0.6.0": { "type": "project", "serviceable": false, "sha512": "" diff --git a/clickonce/LMEMoxaTransfer.dll b/clickonce/LMEMoxaTransfer.dll index 7a2a406..cf329e1 100644 Binary files a/clickonce/LMEMoxaTransfer.dll and b/clickonce/LMEMoxaTransfer.dll differ diff --git a/clickonce/LMEMoxaTransfer.dll.manifest b/clickonce/LMEMoxaTransfer.dll.manifest index 636f434..6b07c3d 100644 --- a/clickonce/LMEMoxaTransfer.dll.manifest +++ b/clickonce/LMEMoxaTransfer.dll.manifest @@ -1,6 +1,6 @@  - + @@ -315,13 +315,13 @@ yJ3y5ECYB7uvuObMawI53X3eO2J8qP27QuUvy6Mqb6Q= - + - Nv4qL0FVotwOp0qThwBv1Tr1b8IhUz9qpLou6U+mSrk= + Q4QNVVMnrboRK/nE1I5KSdH9xm9grdRJVviEAibZY2w= @@ -330,7 +330,7 @@ - SicNxJyLSgEXGUJXoUjrisAwN6uPc8rDwLl7ieFjeF4= + dYrmcUD4rU7mO+e5LuUU1AXv/vbrRbxUUcjUqJvJ5XU= diff --git a/clickonce/LMEMoxaTransfer.exe b/clickonce/LMEMoxaTransfer.exe index 9d2660c..30ef9ed 100644 Binary files a/clickonce/LMEMoxaTransfer.exe and b/clickonce/LMEMoxaTransfer.exe differ diff --git a/clickonce/LMEMoxaTransfer.pdb b/clickonce/LMEMoxaTransfer.pdb index 0ddf04e..67f7cb1 100644 Binary files a/clickonce/LMEMoxaTransfer.pdb and b/clickonce/LMEMoxaTransfer.pdb differ