-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathImportForm.vb
More file actions
326 lines (311 loc) · 12.3 KB
/
ImportForm.vb
File metadata and controls
326 lines (311 loc) · 12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
Imports System.DateTime
Imports System.IO
Imports adif
Imports JJLogLib
Imports JJTrace
Public Class ImportForm
Dim impFile As FileStream
Dim rfs As BinaryReader
Dim session As LogSession
Dim tempFile As String
Dim EOF As Boolean
Dim IOError As Boolean
Const tagChar As Char = "<"
Const tagEnd As Char = ">"
Const tagIntra As Char = ":"c
Const badHeader As String = "Probable malformed ADIF header."
Private Function newExtention(ByVal fn As String, ByVal ext As String) As String
' Return the file name with the new extention.
' ext should not contain the period.
' First get the name w/o the extention.
Dim i As Integer = fn.LastIndexOf("."c)
If i <> -1 Then
fn = fn.Substring(0, i)
End If
fn &= "." & ext
Return fn
End Function
Private Sub ImportForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Tracing.TraceLine("import_load", TraceLevel.Info)
ImportingLabel.Enabled = False
ImportingLabel.Visible = False
DialogResult = DialogResult.None
impFile = Nothing
If ContactLog.Name = vbNullString Then
MsgBox(mustHaveLog)
Tracing.TraceLine("import_load:no log file", TraceLevel.Error)
DialogResult = Windows.Forms.DialogResult.Abort
Return
End If
' Cleanup all ContactLog sessions.
If Not ContactLog.Cleanup Then
' Cleanup not allowed.
DialogResult = Windows.Forms.DialogResult.Abort
Return
End If
' Get the input file.
With OpenFileDialog1
.AddExtension = True
.DefaultExt = "ADI"
.Filter = "ADIF file (*.ADI)|*.ADI|Text file (*.TXT)|*.TXT"
.CheckFileExists = True
.CheckPathExists = True
.FileName = newExtention(CurrentOp.LogFile, "ADI")
.FileName = .SafeFileName
Dim di As DirectoryInfo
di = Directory.GetParent(CurrentOp.LogFile)
.InitialDirectory = di.FullName
.Title = "Input Filename"
.ValidateNames = True
If .ShowDialog = DialogResult.OK Then
Try
impFile = New FileStream(.FileName, FileMode.Open)
rfs = New BinaryReader(impFile)
Catch ex As IOException
Tracing.ErrMessageTrace(ex)
DialogResult = DialogResult.Abort
Return
End Try
End If
FromName.Text = .FileName
' The current logfile is the output. Import to a temporary first though.
ToName.Text = CurrentOp.LogFile
End With
End Sub
Private Sub OkButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OkButton.Click
ImportingLabel.Visible = True
ImportingLabel.Enabled = True
ImportingLabel.Focus()
' Import to a temp file first.
' Note this will originally use the default log, see import().
tempFile = My.Computer.FileSystem.GetTempFileName
Tracing.TraceLine("import tempfile:" & tempFile, TraceLevel.Info)
session = New LogSession(tempFile)
If Not session.Start Then
DialogResult = DialogResult.Abort
Return
End If
' Do the import.
Dim importOK As Boolean = import()
closeFiles()
If importOK Then
DialogResult = DialogResult.OK
' Replace the log with the temp file.
Try
Tracing.TraceLine("import replacing:" & CurrentOp.LogFile, TraceLevel.Info)
File.Delete(CurrentOp.LogFile)
File.Move(tempFile, CurrentOp.LogFile)
' config the log.
ConfigContactLog()
Catch ex As Exception
Tracing.ErrMessageTrace(ex)
DialogResult = DialogResult.Abort
End Try
Else
Tracing.TraceLine("import failed", TraceLevel.Error)
DialogResult = DialogResult.Abort
If File.Exists(tempFile) Then
Try
File.Delete(tempFile)
Catch ex As Exception
' Ignore.
End Try
End If
End If
End Sub
Private Sub CnclButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CnclButton.Click
' Close impFile if needed. impLog won't be open.
closeFiles()
DialogResult = DialogResult.Cancel
End Sub
Private Sub closeFiles()
If impFile IsNot Nothing Then
Try
impFile.Close()
impFile.Dispose()
Catch ex As Exception
Tracing.ErrMessageTrace(ex)
End Try
End If
If session IsNot Nothing Then
session.EndSession()
End If
End Sub
Enum states
initial
findTagEnd
inTag
End Enum
Private Function import() As Boolean
Tracing.TraceLine("import started", TraceLevel.Info)
' Returns false on an I/O error.
' Create the tag names array.
Dim state As states = states.initial
Dim tag As String = ""
Dim sanity As Long = 0
EOF = False
IOError = False
While Not (EOF Or IOError)
' Sanity check.
If sanity > impFile.Length Then
ShowInternalError(ImportHangup)
Return False
End If
sanity = sanity + 1 ' note that sanity is not an input character count
Select Case state
Case states.initial
' Looking for a tag.
If read(1) = tagChar Then
' This might be a tag.
state = states.findTagEnd
tag = ""
End If
Case states.findTagEnd
' Looking for a tag terminator.
Dim c As String = read(1)
If c = tagChar Then
' Oops, tag begin char found.
tag = ""
ElseIf c = tagEnd Then
' Found "<tag>".
state = states.inTag
Else
' Add this to the tag.
tag &= c
End If
Case states.inTag
' Have a potential tag.
Dim fld As LogFieldElement = doTag(tag)
If fld Is Nothing Then
If IOError Then
Exit While
End If
' We don't handle this tag, or it's bogus. Start over.
Else
' We handle this one.
' Check for record end
If fld.ADIFTag = AdifTags.ADIF_HeaderEnd Then
If Not session.UpdateLogHeader() Then
IOError = True
Exit While
End If
' Now restart the session with the new header.
session.EndSession()
session = New LogSession(tempFile)
If Not session.Start() Then
MsgBox(badHeader)
IOError = True
Exit While
End If
ElseIf fld.ADIFTag = AdifTags.ADIF_RecordEnd Then
' See if we need to tack on the record version.
If (session.FormData.RecordVersion <> vbNullString) Then
session.SetFieldText(AdifTags.iADIF_RecordVersion, session.FormData.RecordVersion)
End If
If Not session.Append Then
IOError = True
Exit While
End If
session.Clear()
End If
End If
state = states.initial
End Select
End While
Return Not IOError
End Function
Private Function doTag(ByVal tag As String) As LogFieldElement
' tag should have the form ADIFTag:Length[:type].
' The ADIFTag can be mixed case.
' Only specified ADIF tags are processed along with EOH and EOR.
' The file must be positioned immediately following the tagEndChar.
Dim rv As LogFieldElement = Nothing
' Check for an end tag.
Dim tagText As String = tag.ToUpper
If (tagText = AdifTags.ADIF_HeaderEnd) Or (tagText = AdifTags.ADIF_RecordEnd) Then
rv = New LogFieldElement(tagText)
Return rv
End If
Dim tagTextLen As Integer = tag.IndexOf(tagIntra)
If (tagTextLen = -1) Or (tagTextLen = tag.Length - 1) Then
' Covers the case where tag = "".
Return rv
End If
' Get the length. We ignore the type for now.
Dim tagLenLen As Integer = tag.Substring(tagTextLen + 1).IndexOf(tagIntra)
If tagLenLen = -1 Then
tagLenLen = tag.Length - tagTextLen - 1
End If
Dim tagContentLen As Integer
Try
tagContentLen = tag.Substring(tagTextLen + 1, tagLenLen)
Catch ex As Exception
' Not numeric
Return rv
End Try
' Looks like an ADIF tag.
' LogEntry.ADIFTags are uppercase.
tagText = tag.Substring(0, tagTextLen).ToUpper
' Get the associated LogFieldElement from the session.
' We treat the LOTW_QSL and EQSL_QSL tags as QSL tags.
If (tagTextLen > 8) AndAlso _
((tagText.Substring(0, 8) = "LOTW_QSL") Or (tagText.Substring(0, 8) = "EQSL_QSL")) Then
tagText = tagText.Substring(4)
End If
rv = getTag(tagText)
If rv IsNot Nothing Then
' A valid tag we handle.
rv.Data = read(tagContentLen)
If rv.Data Is Nothing Then
rv = Nothing
Else
Select Case rv.ADIFTag
Case AdifTags.ADIF_RXFreq, AdifTags.ADIF_TXFreq
' Show the frequencies as mhz.khz.hz.
rv.Data = FormatFreq(FormatFreqForRadio(rv.Data))
Case AdifTags.ADIF_DateOn, AdifTags.ADIF_DateOff
If rv.Data.Length = 8 Then
Dim str As String = rv.Data.Substring(4, 2) & "/" & _
rv.Data.Substring(6, 2) & "/" & rv.Data.Substring(0, 4)
rv.Data = str
End If
Case AdifTags.HDR_LogHeaderVersion
' The log header will be at the current version.
rv.Data = LogClass.CurrentHeaderVersion
Case Else
' See if special processing required.
Dim fldType As AdifTags.ADIFTypeField = Nothing
If AdifTags.ADIFTypeDictionary.TryGetValue(tagText, fldType) AndAlso _
(fldType.type = AdifTags.ADIFTypeInternal) Then
rv.Data = fldType.ADIFToInternal(rv.Data)
End If
End Select
End If
End If
Return rv
End Function
Private Function getTag(tag As String) As LogFieldElement
Dim rv As LogFieldElement
rv = session.getField(tag, False, session.HeaderDictionary)
If rv Is Nothing Then
rv = session.getField(tag, False, session.FieldDictionary)
End If
Return rv
End Function
Private Function read(ByVal len As Integer) As String
' This can set EOF and IOError.
If (impFile.Position + len) > impFile.Length Then
EOF = True
Return Nothing
End If
Dim buf(len - 1) As Char
Try
buf = rfs.ReadChars(len)
Catch ex As Exception
Tracing.ErrMessageTrace(ex)
IOError = True
Return Nothing
End Try
Return CStr(buf)
End Function
End Class