Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 7716edfa authored by Kostis ANAGNOSTOPOULOS's avatar Kostis ANAGNOSTOPOULOS
Browse files

PrefsUI: Add OK, Save, Cancel buttons, store only when Dirty.

* json: Allow null for /Header/StrictBody.
* log: Show full ex in ErrorTab when logLevelThreshold <= 2.
parent 21e81b68
No related branches found
No related tags found
No related merge requests found
......@@ -41,13 +41,14 @@ Partial Class F_Preferences
Me.ButtonSelectNotepad = New System.Windows.Forms.Button()
Me.editor = New System.Windows.Forms.TextBox()
Me.GroupBox1 = New System.Windows.Forms.GroupBox()
Me.hideUsername = New System.Windows.Forms.CheckBox()
Me.strictBodies = New System.Windows.Forms.CheckBox()
Me.includeSchemas = New System.Windows.Forms.CheckBox()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.Label3 = New System.Windows.Forms.Label()
Me.CheckBox1 = New System.Windows.Forms.CheckBox()
Me.ButtonReload = New System.Windows.Forms.Button()
Me.hideUsername = New System.Windows.Forms.CheckBox()
Me.ButtonSave = New System.Windows.Forms.Button()
Me.GroupBoxWorDir.SuspendLayout()
Me.GroupBoxInterface.SuspendLayout()
Me.TabControl1.SuspendLayout()
......@@ -92,14 +93,14 @@ Partial Class F_Preferences
Me.ButtonOK.Name = "ButtonOK"
Me.ButtonOK.Size = New System.Drawing.Size(75, 23)
Me.ButtonOK.TabIndex = 0
Me.ButtonOK.Text = "Save"
Me.ButtonOK.Text = "OK"
Me.ButtonOK.UseVisualStyleBackColor = True
'
'ButtonCancel
'
Me.ButtonCancel.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.ButtonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.ButtonCancel.Location = New System.Drawing.Point(99, 248)
Me.ButtonCancel.Location = New System.Drawing.Point(355, 248)
Me.ButtonCancel.Name = "ButtonCancel"
Me.ButtonCancel.Size = New System.Drawing.Size(75, 23)
Me.ButtonCancel.TabIndex = 1
......@@ -241,6 +242,16 @@ Partial Class F_Preferences
Me.GroupBox1.TabStop = False
Me.GroupBox1.Text = "JSON"
'
'hideUsername
'
Me.hideUsername.AutoSize = True
Me.hideUsername.Location = New System.Drawing.Point(6, 67)
Me.hideUsername.Name = "hideUsername"
Me.hideUsername.Size = New System.Drawing.Size(94, 17)
Me.hideUsername.TabIndex = 12
Me.hideUsername.Text = "hideUsername"
Me.hideUsername.UseVisualStyleBackColor = True
'
'strictBodies
'
Me.strictBodies.AutoSize = True
......@@ -297,15 +308,16 @@ Partial Class F_Preferences
Me.ButtonReload.Text = "Reload"
Me.ButtonReload.UseVisualStyleBackColor = True
'
'hideUsername
'ButtonSave
'
Me.hideUsername.AutoSize = True
Me.hideUsername.Location = New System.Drawing.Point(6, 67)
Me.hideUsername.Name = "hideUsername"
Me.hideUsername.Size = New System.Drawing.Size(94, 17)
Me.hideUsername.TabIndex = 12
Me.hideUsername.Text = "hideUsername"
Me.hideUsername.UseVisualStyleBackColor = True
Me.ButtonSave.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.ButtonSave.DialogResult = System.Windows.Forms.DialogResult.OK
Me.ButtonSave.Location = New System.Drawing.Point(99, 248)
Me.ButtonSave.Name = "ButtonSave"
Me.ButtonSave.Size = New System.Drawing.Size(75, 23)
Me.ButtonSave.TabIndex = 13
Me.ButtonSave.Text = "Save"
Me.ButtonSave.UseVisualStyleBackColor = True
'
'F_Preferences
'
......@@ -314,6 +326,7 @@ Partial Class F_Preferences
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.CancelButton = Me.ButtonCancel
Me.ClientSize = New System.Drawing.Size(515, 283)
Me.Controls.Add(Me.ButtonSave)
Me.Controls.Add(Me.TabControl1)
Me.Controls.Add(Me.ButtonCancel)
Me.Controls.Add(Me.ButtonReload)
......@@ -363,4 +376,5 @@ Partial Class F_Preferences
Friend WithEvents strictBodies As System.Windows.Forms.CheckBox
Friend WithEvents includeSchemas As System.Windows.Forms.CheckBox
Friend WithEvents hideUsername As System.Windows.Forms.CheckBox
Friend WithEvents ButtonSave As System.Windows.Forms.Button
End Class
......@@ -2,8 +2,7 @@ Imports Newtonsoft.Json.Linq
Public Class F_Preferences
' Load confic
Private Sub F03_Options_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Private Sub FormLoadHandler(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim controlPairs As IList(Of Control()) = New List(Of Control())
'' CONTROL LABEL
controlPairs.Add({Me.workingDir, Me.GroupBoxWorDir})
......@@ -15,37 +14,82 @@ Public Class F_Preferences
controlPairs.Add({Me.strictBodies, Nothing})
controlPairs.Add({Me.hideUsername, Nothing})
'' Add help-tooltips from Json-Schema.
'' Add help-tooltips from Json-Schema and
'' dirty-check them.
''
Dim schema = JObject.Parse(cPreferences.JSchemaStr)
For Each row In controlPairs
Dim ctrl = row(0)
Dim Label = row(1)
updateControlsFromSchema(schema, ctrl, Label)
If TypeOf ctrl Is CheckBox Then
AddHandler DirectCast(ctrl, CheckBox).CheckedChanged, AddressOf DirtyHandler
Else
AddHandler ctrl.TextChanged, AddressOf DirtyHandler
End If
Next
UI_PopulateFrom(Prefs)
End Sub
Private Sub FormClosingHandler(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If Me.Dirty Then
Dim res = MsgBox("Save changes?", MsgBoxStyle.YesNoCancel, "Preferences Changed")
Select Case res
Case MsgBoxResult.No
Case MsgBoxResult.Yes
Try
StorePrefs()
Catch ex As Exception
e.Cancel = True
logme(9, True, format("Failed storing Preferences({0}) due to: {1} \n Preferences left unmodified!", _
PrefsPath, ex.Message), ex)
End Try
Case Else
e.Cancel = True
End Select
End If
End Sub
Private _Dirty
Private Property Dirty As Boolean
Get
Return _Dirty
End Get
Set(ByVal value As Boolean)
If _Dirty Xor value Then
Me.Text = "Preferences" & IIf(value, "*", "")
End If
_Dirty = value
End Set
End Property
Private Sub DirtyHandler(ByVal sender As Object, ByVal e As System.EventArgs)
Dirty = True
End Sub
Private Sub UI_PopulateFrom(ByVal value As cPreferences)
' Allocate the data from the confic file (Only by the start)
Me.workingDir.Text = value.workingDir
Me.editor.Text = value.Editor
Me.writeLog.Checked = value.WriteLog
Me.logLevel.Text = value.LogLevel
Me.logSize.Text = value.LogSize
Me.includeSchemas.Checked = value.IncludeSchemas
Me.editor.Text = value.editor
Me.writeLog.Checked = value.writeLog
Me.logLevel.Text = value.logLevel
Me.logSize.Text = value.logSize
Me.includeSchemas.Checked = value.includeSchemas
Me.strictBodies.Checked = value.strictBodies
Me.hideUsername.Checked = value.hideUsername
Me.Dirty = False
End Sub
Private Sub UI_PopulateTo(ByVal value As cPreferences)
value.workingDir = Me.workingDir.Text
value.Editor = Me.editor.Text
value.WriteLog = Me.writeLog.Checked
value.LogLevel = Me.logLevel.Text
value.LogSize = Me.logSize.Text
value.IncludeSchemas = Me.includeSchemas.Checked
value.editor = Me.editor.Text
value.writeLog = Me.writeLog.Checked
value.logLevel = Me.logLevel.Text
value.logSize = Me.logSize.Text
value.includeSchemas = Me.includeSchemas.Checked
value.strictBodies = Me.strictBodies.Checked
value.hideUsername = Me.hideUsername.Checked
End Sub
......@@ -57,28 +101,34 @@ Public Class F_Preferences
End If
End Sub
' Ok button
Private Sub StorePrefs(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOK.Click
Private Sub SaveHandler(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOK.Click, ButtonSave.Click
Try
Dim newPrefs As cPreferences = Prefs.Clone()
UI_PopulateTo(newPrefs)
' Write the config file
newPrefs.Store(PrefsPath, newPrefs)
Prefs = newPrefs ' Replace active prefs if successful.
' Message for the restart of VECTO
RestartN = True
logme(7, True, format("Stored Preferences({0}). \n\nDo you want to restart VECTO now?", PrefsPath))
' Close the window
Me.Close()
'' OK-btn save when dirty, always closes-form.
'' Save-btn: always saves, burt not closes-form.
''
If sender IsNot ButtonOK OrElse Me.Dirty Then
StorePrefs()
End If
If sender Is ButtonOK Then Me.Close()
Catch ex As Exception
logme(9, True, format("Failed storing Preferences({0}) due to: {1} \n Preferences left unmodified!", _
PrefsPath, ex.Message), ex)
End Try
End Sub
Private Sub StorePrefs()
Dim newPrefs As cPreferences = Prefs.Clone()
UI_PopulateTo(newPrefs)
' Write the config file
newPrefs.Store(PrefsPath, newPrefs)
Prefs = newPrefs ' Replace active prefs if successful.
Me.Dirty = False
' Message for the restart of VECTO
logme(7, False, format("Stored Preferences({0}).", PrefsPath))
End Sub
' Ok button
Private Sub ReloadPrefs(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonReload.Click
......@@ -150,5 +200,6 @@ Public Class F_Preferences
Private Sub TextBoxLogSize_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles logSize.Leave, TextBox1.Leave
If Me.logSize.Text = Nothing Then Me.logSize.Text = Prefs.PropDefault("logSize")
End Sub
End Class
......@@ -10,8 +10,17 @@ Imports System.Globalization
''' and delegates the Body-building and its validation almost entirely to sub-classes.
''' </summary>
''' <remarks>
''' The /Header/Strict boolean controls whether to allow additional-properties in Body,
''' so it can be used to debug input-files by manually setting it to 'true' with a text-editor.
''' JSON files do not support comments, but help is provided by their accompanying json-schemas (see below).
''' They are splitted in two sections, Header and Body. The Header contains administrational fields or fields
''' related to the actual parsing of the file.
'''
''' Of interest are the following 2 of Header’s properties:
''' • /Header/StrictBody: Controls whether the application will accept any unknown body-properties
''' while reading the file. Set it to true to debug malformed input-files, ie to detect accidentally
''' renamed properties.
''' • /Header/BodySchema: The JSON-schema of the body will be placed HERE, for documenting file.
''' When true, it is always replaced by the Body's schema on the next save. When false, it overrides
''' application's choice and is not replaced ever.
''' </remarks>
Public MustInherit Class cJsonFile
Implements ICloneable
......@@ -28,7 +37,7 @@ Public MustInherit Class cJsonFile
"AppVersion": null,
"ModifiedDate": null,
"CreatedBy": null,
"StrictBody": false,
"StrictBody": null,
"BodySchema": null,
},
"Body": null
......@@ -70,17 +79,19 @@ Public MustInherit Class cJsonFile
},
"StrictBody": {
"title": "Validate body strictly",
"type": "boolean",
"description": "When True, the 'Body' does not accept unknown properties.",
"default": false,
"type": ["boolean", "null"],
"description": "If set to true, the application will not accept any unknown body-properties while reading this file.
When null/property missing, the application decides what to do.
It is useful for debugging malformed input-files, ie to detect accidentally renamed properties.",
"default": null,
},
"BodySchema": {
"title": "Body schema",
"type": ["boolean", "object", "null"],
"description": "Body schema is included HERE, for documenting file. \n _
When null/property missing, application decides what to do. \n _
When True, it is always replaced by the Body's schema on the next save.\n _
When False, it overrides Application's choice and is not replaced ever.",
"description": "Body schema is included HERE, for documenting file.
When null/property missing, the application decides what to do.
When True, it is always replaced by the Body's schema on the next save.
When False, it overrides Application's choice and is not replaced ever.",
"default": null,
},
}
......@@ -177,8 +188,11 @@ Public MustInherit Class cJsonFile
h("CreatedBy") = format("{0}{1}(lic: {2})", username, Lic.LicString, Lic.GUID)
h("AppVersion") = AppVers
'' Ensure StrictBody element always there.
If h("StrictBody") Is Nothing Then
h("StrictBody") = False
h("StrictBody") = Nothing
End If
'' Decide whether to include body-schema in header (for documenting file),
......@@ -210,8 +224,8 @@ Public MustInherit Class cJsonFile
End Sub
''' <exception cref="FormatException">includes all validation errors</exception>
''' <param name="prefs">It is there to be used when storing cPreferences themselfs.</param>
''' <param name="strictHeader">when false, relaxes Header's schema (used on Loading to be more accepting)</param>
''' <param name="prefs">It is there just to be used when storing cPreferences themselfs.</param>
Friend Sub Validate(Optional ByVal strictHeader As Boolean = False, Optional ByVal prefs As cPreferences = Nothing)
If prefs Is Nothing Then prefs = CSE.Prefs
Dim validateMsgs As IList(Of String) = New List(Of String)
......@@ -227,9 +241,7 @@ Public MustInherit Class cJsonFile
Dim dummy = New cSemanticVersion(Me.FileVersion) '' Just to ensure its syntax.
'' Validate Body by subclass
Dim hsb = Me.Header("StrictBody")
Dim strictBody As Boolean = IIf(hsb Is Nothing, Prefs.strictBodies, hsb)
Me.ValidateBody(strictBody, validateMsgs)
Me.ValidateBody(Me.StrictBody, validateMsgs)
If (validateMsgs.Any()) Then
Throw New FormatException(format("Validating /Body failed due to: {0}", String.Join(vbCrLf, validateMsgs)))
......@@ -249,7 +261,17 @@ Public MustInherit Class cJsonFile
If obj Is Nothing OrElse Not Me.GetType().Equals(obj.GetType()) Then
Return False
Else
Return JToken.DeepEquals(Me.Content, DirectCast(obj, cJsonFile).Content)
Dim oj As cJsonFile = DirectCast(obj, cJsonFile)
If Not JToken.DeepEquals(Me.Body, oj.Body) Then Return False
'' Compare Headers without the 'ModifiedDate' field
'' which would undoublfully different each time.
Dim mh As New JObject(Me.Header)
Dim oh As New JObject(oj.Header)
mh.Remove("ModifiedDate")
oh.Remove("ModifiedDate")
Return JToken.DeepEquals(mh, oh)
End If
End Function
......@@ -331,12 +353,18 @@ Public MustInherit Class cJsonFile
Public ReadOnly Property StrictBody As Boolean
Get
Dim value = Me.Body("StrictBody")
Return IIf(value Is Nothing OrElse value.Type = JTokenType.Null, False, value)
Dim value = False
Dim jt = Me.Header("StrictBody")
If jt IsNot Nothing AndAlso jt.Type <> JTokenType.Null Then
value = jt
ElseIf Prefs IsNot Nothing Then
value = Prefs.strictBodies
End If
Return value
End Get
End Property
'' NO, logic behind it more complex, see UpdateHeader() instead.
'' NO, logic behind it too complex, see UpdateHeader() instead.
'Public ReadOnly Property BodySchema As Boolean
' Get
' Dim value = Me.Body("BodySchema")
......
......@@ -60,7 +60,7 @@ Public Class cPreferences
"minimum": 0,
"maximum": 10, "exclusiveMaximum": true,
"default": 2,
"description": "Sets the threshold(Level) above (inclusive) from which log-messages are shown in the log-window.
"description": "Sets the threshold(Level) above (inclusive) from which log-messages are shown in the log-window.
0 : All
3-7 : No infos
8 : No warnings
......@@ -76,17 +76,17 @@ Public Class cPreferences
"title": "Strict Bodies",
"type": "boolean",
"default": false,
"description": "When set to true, any unknown body-properties are not accepted when reading JSON-files.
It is useful for debugging malformed input-files, ie to detect
accidentally renamed properties.
"description": "If set to true, the application will not accept any unknown body-properties when reading JSON-files.
It is useful for debugging malformed input-files, ie to detect accidentally renamed properties.
Each file can override it by setting its `/Header/StrictBody` property.",
},
"includeSchemas": {
"title": "Include Schemas",
"type": "boolean",
"default": false,
"description": "When set to true the JSON-files are self-documented by populating their `/Header/BodySchema` property.
Each file can override it by setting its `/Header/BodySchema` property to false/true.",
"description": "When set to true the JSON-files are self-documented by
populating their `/Header/BodySchema` property. Each file can override it by
setting its `/Header/BodySchema` property to false/true.",
},
"hideUsername": {
"title": "Hide Username",
......
......@@ -260,9 +260,11 @@ Module utils
Private Sub updateLogWindow(ByVal logFileLevel As Integer, ByVal text As String, ByVal tabLabel As String, ByVal ex As Exception)
' Established the text wit the symbol from the style
Dim printEx = False
If (ex IsNot Nothing) Then
text = text & " (Check log-file for details)"
printEx = (logFileLevel > 1 AndAlso Prefs.logLevel <= 2)
text = format("{0} (Check {1} for details)", text, IIf(printEx, "error/warn tab", "log-file"))
End If
' Write to Log-windows
......@@ -271,8 +273,14 @@ Module utils
F_Main.ListBoxMSG.Items.Add(text)
F_Main.ListBoxWar.Items.Add(text)
F_Main.TabPageWar.Text = format("Warnings({0})", F_Main.ListBoxWar.Items.Count)
If printEx Then
F_Main.ListBoxWar.Items.Add(format("\i{0}", ex))
End If
Case 3 ' Error
F_Main.ListBoxErr.Items.Add(text)
If printEx Then
F_Main.ListBoxErr.Items.Add(format("\i{0}", ex))
End If
F_Main.TabPageErr.Text = format("Errors({0})", F_Main.ListBoxErr.Items.Count)
Case Else
'' ignored
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment