diff --git a/CHANGES.md b/CHANGES.md index ced75e17f7443a2e2cb1db0e2dbf9cb222e00929..31ae967701f5d8b287c283e5a34916036fce3ed9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,12 +1,30 @@ VECTO-CSE's Changes =================== + +#### 2014-05-29: 2.0.1-pre1 #### +JRC contributions: + * Read/write Vehicle-file as JSON. + * prefsUI: Add Reload button. + * Remember window-location (use .net Settings for that). + * Start logging stack-traces in the file-log. +##### Internal: + * Start saving stack-traces into the log-file. + * Enhance JSON-files with standard header/body behavior. + * Link JSON to GUI controls (labels & toolstips) + * json: Read defaults from schemas. -### 2014-05-23: CSE-2.0.1-pre0 -* Remove the versioning infos from app-name (manual, project-name, folders). -* Possible to use any editor (not only notepad.exe). -* Separate config/ from Declaration/ folders. -* Added README.md, CHANGES.md, COPYING.txt files. -#### Internal: -* Auto create config/ on the 1st run, convert it to JSON with transparent error-handling. -* FIX leaking of file-descriptors by using VB's 'Using' statement (class 'cFile_v3' now implements IDisposeable). +#### 2014-05-23: 2.0.1-pre0 #### +JRC contributions: + * Remove the versioning infos from app-name (manual, project-name, folders). + * Use SemanticVersioning 2.0.0 (see http://semver.org/). + * Possible to use any editor (not only notepad.exe). + * Separate config/ from Declaration/ folders. + * Added README.md, CHANGES.md, COPYING.txt files. +##### Internal: + * Auto create config/ on the 1st run, converted to JSON with transparent error-handling. + * FIX leaking of file-descriptors by using VB's 'Using' statement (class 'cFile_v3' now implements IDisposeable). + + +#### 2014-05-14: CSE2.01 #### +1st delivery from TU-Graz under Lot-3. diff --git a/CSE/Classes/cJsonFile.vb b/CSE/Classes/cJsonFile.vb index 8db384943e4dc2bacedfa2e23b93f60ffb605ff5..13a2b9495cc9e1c939f5dba5b2a5df10d20c935a 100644 --- a/CSE/Classes/cJsonFile.vb +++ b/CSE/Classes/cJsonFile.vb @@ -69,9 +69,12 @@ Public MustInherit Class cJsonFile }, "BodySchema": { "title": "Body schema", - "type": ["boolean", "object"], - "description": "When set to True, it is replaced by the Body's schema on the next save, so as to provide users with documentation on the file.", - "default": false, + "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.", + "default": null, }, } }, @@ -90,7 +93,7 @@ Public MustInherit Class cJsonFile ''' <summary>When a instance_with_defauls is Created, it gets its /Body from this method</summary> ''' <remarks>The result json must be valid after replacing with this body.</remarks> - Protected MustOverride Function BodySchema() As JObject + Public MustOverride Function BodySchema() As JObject ''' <summary>Invoked by this class for subclasses to validate file</summary> ''' <remarks>To signify validation-failure it can throw an exception or add err-messages into the supplied list</remarks> @@ -135,7 +138,7 @@ Public MustInherit Class cJsonFile WriteJsonFile(fpath, Json_Contents) End Sub - + ''' <summary>Maintains header's standard props and overlays any props from subclass.</summary> Sub UpdateHeader() Dim h As JObject = Me.Header @@ -145,16 +148,22 @@ Public MustInherit Class cJsonFile h("StrictBody") = False End If - '' Add schema for documenting file according to its boolean(/Header/BodySchema) if any or failback to global prefs:/Body/IncludeSchemas. - '' + '' Decide whether to include body-schema in header (for documenting file), + '' by checking the folllowing, ordered by priority: + '' 1. jsonfile:/Header/BodySchema + '' 2. prefs:/Body/IncludeSchemas + '' 2.b. prefschema:/properties/Body/properties/IncludeSchemas/default (implict by cPreferences.IncludeSchemas property) + '' 3. false + Dim isIncludeSchema As Boolean Dim bodySchema = h("BodySchema") - Dim includeSchema = False - If bodySchema Is Nothing AndAlso AppPreferences IsNot Nothing Then - includeSchema = AppPreferences.IncludeSchemas - ElseIf bodySchema IsNot Nothing AndAlso bodySchema.Type = JTokenType.Boolean Then - includeSchema = bodySchema + If bodySchema IsNot Nothing AndAlso bodySchema.Type = JTokenType.Boolean Then + isIncludeSchema = bodySchema + ElseIf AppPreferences IsNot Nothing Then + isIncludeSchema = AppPreferences.IncludeSchemas + Else + isIncludeSchema = False End If - If includeSchema Then + If isIncludeSchema Then h("BodySchema") = Me.BodySchema End If @@ -207,6 +216,26 @@ Public MustInherit Class cJsonFile End If End Function + ''' <summary>Used by sublasses to implement Propety-Get with defaults when non-existent</summary> + ''' <param name="propPath">The JSON.net's XPath for a Body property, including the starting dot('.'). + ''' + ''' Examples: + ''' PROP REQUESTED 'propPath' ARGUMENT + ''' -------------- ------------------- + ''' /Body/SomeProp' --> .SomeProp + ''' /Body/someGroup/somePropName --> .someGroup.somePropName'. + ''' </param> + Protected Function BodyGetter(ByVal propPath As String) As JToken + Dim value As JToken = Me.Body.SelectToken(propPath) + If value Is Nothing Then '' No prop existed + '' Return a default from schema (if any). + '' + Dim schemaPath = propPath.Replace(".", ".properties.") + Return Me.BodySchema.SelectToken(schemaPath & ".default") + Else + Return value + End If + End Function #Region "json props" Protected ReadOnly Property Header() As JObject @@ -245,10 +274,18 @@ Public MustInherit Class cJsonFile Public ReadOnly Property StrictBody As Boolean Get Dim value = Me.Body("StrictBody") - Return IIf(value Is Nothing, False, value) + Return IIf(value Is Nothing OrElse value.Type = JTokenType.Null, False, value) End Get End Property + '' NO, logic behind it more complex, see UpdateHeader() instead. + 'Public ReadOnly Property BodySchema As Boolean + ' Get + ' Dim value = Me.Body("BodySchema") + ' Return IIf(value Is Nothing OrElse value.Type = JTokenType.Null, False, value) + ' End Get + 'End Property + #End Region ' "json props" End Class diff --git a/CSE/Classes/cPreferences.vb b/CSE/Classes/cPreferences.vb index 78d0c77c16291a6bead8807cbf0488e1fbca5893..ac8074936a25256af8bd5449cfe25c150ac1249d 100644 --- a/CSE/Classes/cPreferences.vb +++ b/CSE/Classes/cPreferences.vb @@ -13,64 +13,84 @@ Public Class cPreferences }</json>.Value) End Function - ' Default-prefs specified here. + ' Defaults specified here. Protected Overrides Function BodyContent() As JObject - Return JObject.Parse(<json>{ - "WorkingDir": null, - "WriteLog": true, - "LogSize": 2, - "LogLevel": 5, - "Editor": "notepad.exe", - }</json>.Value) + '' Return empty body since all proprs are optional. + '' They will become concrete on the 1st store. + Return New JObject() + 'Return JObject.Parse(<json>{ + ' "workingDir": null, + ' "writeLog": true, + ' "logSize": 10, + ' "logLevel": 5, + ' "editor": "notepad.exe", + ' }</json>.Value) End Function - Protected Overrides Function BodySchema() As JObject + Public Overrides Function BodySchema() As JObject Return JObject.Parse(JSchemaStr()) End Function ''' <param name="allowAdditionalProps">when false, more strict validation</param> - Protected Function JSchemaStr(Optional ByVal allowAdditionalProps As Boolean = True) As String + Public Shared Function JSchemaStr(Optional ByVal allowAdditionalProps As Boolean = True) As String Dim allowAdditionalProps_str As String = IIf(allowAdditionalProps, "true", "false") Return <json>{ "title": "Schema for vecto-cse PREFERENCES", "type": "object", "additionalProperties": <%= allowAdditionalProps_str %>, "required": true, "properties": { - "WorkingDir": { + "workingDir": { + "title": "Working Directory", "type": ["string", "null"], - "required": false, "default": null, - "description": "Last used Working Directory Path for input/output files, when null/empty, uses app's dir", + "description": "The path of the Working Directory for input/output files. \nWhen null/empty, app's dir implied.", }, - "WriteLog": { + "writeLog": { + "title": "Log to file", "type": "boolean", - "required": true, - "description": "Whether to write messages to log file (default: true)", + "default": true, + "description": "Whether to write messages to log file.", }, - "LogSize": { + "logSize": { + "title": "Log-file's limit", "type": "integer", - "required": true, - "description": "Allowed Log-file size limit [MiB] (default: 2)", + "minimum": 0, + "default": 10, + "description": "Allowed Log-file size limit [MiB].", }, - "LogLevel": { + "logLevel": { + "title": "Log-window's Level", "type": "integer", - "required": true, - "description": "Message Output Level (default: 5 - 'info')", + "minimum": 0, + "maximum": 10, "exclusiveMaximum": true, + "default": 5, + "description": "Sets the threshold(Level) above from which log-messages to appear in the log-window. + 0 : All + 3-7 : No infos + 8 : No warnings + 9 : Not even errors! + other : Nothing at all", }, - "Editor": { + "editor": { "type": "string", - "required": true, - "description": "Path (or filename if in PATH) of some (text or JSON) editor (default: 'notepad.exe')", + "default": "notepad.exe", + "description": "Path (or just the filename, if in PATH) of a text editor.", }, - "StrictBodies": { + "strictBodies": { + "title": "Strict Bodies", "type": "boolean", "default": false, - "description": "The global-default to use when reading JSON-files without a /Header/StrictBody property.", + "description": "Controls whether unknown body-properties are accepted 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": { + "includeSchemas": { + "title": "Include Schemas", "type": "boolean", - "default": true, - "description": "When true, provides documentation to json-files by populating their Header/BodySchema element when storing them, unless it is already set to false.", + "default": false, + "description": "Controls whether to self-document JSON-files by populating their '/Header/BodySchema' property. +Each file can override it by setting its '/Header/BodySchema' property to false/true.", }, } }</json>.Value @@ -109,10 +129,10 @@ Public Class cPreferences #Region "json props" - Public Property WorkingDir As String + Public Property workingDir As String Get - Dim value As String = Me.Body("WorkingDir") - If value Is Nothing OrElse value.Trim().Length = 0 Then + Dim value As String = Me.Body("workingDir") + If value Is Nothing OrElse String.IsNullOrWhiteSpace(value) Then Return MyPath ElseIf IO.Path.IsPathRooted(value) Then Return value @@ -157,70 +177,64 @@ Public Class cPreferences '' NOTE: Early-binding makes Nulls end-up as 'string' schema-type. '' If value Is Nothing Then - Me.Json_Contents("Body")("WorkingDir") = Nothing + Me.Json_Contents("Body")("workingDir") = Nothing Else - Me.Json_Contents("Body")("WorkingDir") = value + Me.Json_Contents("Body")("workingDir") = value End If End Set End Property - Public Property WriteLog As Boolean + Public Property writeLog As Boolean Get - Return Me.Body("WriteLog") + Return BodyGetter(".writeLog") End Get Set(ByVal value As Boolean) - Me.Body("WriteLog") = value + Me.Body("writeLog") = value End Set End Property - Public Property LogSize As Integer + Public Property logSize As Integer Get - Return Me.Body("LogSize") + Return BodyGetter(".logSize") End Get Set(ByVal value As Integer) - Me.Body("LogSize") = value + Me.Body("logSize") = value End Set End Property - Public Property LogLevel As Integer + Public Property logLevel As Integer Get - Return Me.Body("LogLevel") + Return BodyGetter(".logLevel") End Get Set(ByVal value As Integer) - Me.Body("LogLevel") = value + Me.Body("logLevel") = value End Set End Property - Public Property Editor As String + Public Property editor As String Get - Return Me.Body("Editor") + Return BodyGetter(".editor") End Get Set(ByVal value As String) - If value Is Nothing OrElse value.Trim().Length = 0 Then - value = "notepad.exe" - End If - - Me.Body("Editor") = value + Me.Body("editor") = value End Set End Property - Public Property StrictBodies As Boolean + Public Property strictBodies As Boolean Get - Dim value = Me.Body("StrictBodies") - Return IIf(value Is Nothing, False, value) + Return BodyGetter(".strictBodies") End Get Set(ByVal value As Boolean) - Me.Body("StrictBodies") = value + Me.Body("strictBodies") = value End Set End Property - Public Property IncludeSchemas As Boolean + Public Property includeSchemas As Boolean Get - Dim value = Me.Body("IncludeSchemas") - Return IIf(value Is Nothing, False, value) + Return BodyGetter(".includeSchemas") End Get Set(ByVal value As Boolean) - Me.Body("IncludeSchemas") = value + Me.Body("includeSchemas") = value End Set End Property diff --git a/CSE/GUI/FB_Dialog.vb b/CSE/GUI/FB_Dialog.vb index 01aaf6a74991218c49afcb7a3ad45cfb3620abf6..3609793beca97bae302a7bbcded31e5ef0807f31 100644 --- a/CSE/GUI/FB_Dialog.vb +++ b/CSE/GUI/FB_Dialog.vb @@ -687,7 +687,7 @@ Public Class FB_Dialog 'ButtonWorkDir_Click Private Sub ButtonWorkDir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonWorkDir.Click - SetFolder(AppPreferences.WorkingDir) + SetFolder(AppPreferences.workingDir) End Sub 'ButtonDesktop_Click diff --git a/CSE/GUI/F_Main.vb b/CSE/GUI/F_Main.vb index ed2d3458988d94e2cac08767dbb2c65db5cf52a1..d76731cc3400d78984ba8fed800c59efd43c8d77 100644 --- a/CSE/GUI/F_Main.vb +++ b/CSE/GUI/F_Main.vb @@ -42,8 +42,8 @@ Public Class F_Main ' Polling if the working dir exist (If not then generate the folder) ' - If Not IO.Directory.Exists(AppPreferences.WorkingDir) Then - IO.Directory.CreateDirectory(AppPreferences.WorkingDir) + If Not IO.Directory.Exists(AppPreferences.workingDir) Then + IO.Directory.CreateDirectory(AppPreferences.workingDir) End If ' Write the beginning in the Log @@ -56,7 +56,7 @@ Public Class F_Main Me.Close() End If - ' Write a defailt config file if failed to read one. + ' Write a defult config file if failed to read one. If Not configL Then Try AppPreferences.Store(PreferencesPath) @@ -78,7 +78,7 @@ Public Class F_Main ' Open the filebrowser for the selection of the vehiclefile Private Sub ButtonSelectVeh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectVeh.Click ' Open the filebrowser with the *.csveh parameter - If fbVEH.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbVEH.OpenDialog(AppPreferences.workingDir, False) Then If (fbVEH.Files(0) <> Nothing) Then Me.TextBoxVeh1.Text = fbVEH.Files(0) End If @@ -97,7 +97,7 @@ Public Class F_Main ' Open the filebrowser for the selection of the weatherfile Private Sub ButtonSelectWeather_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectWeather.Click ' Open the filebrowser with the *.cswea parameter - If fbAMB.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbAMB.OpenDialog(AppPreferences.workingDir, False) Then If (fbAMB.Files(0) <> Nothing) Then Me.TextBoxWeather.Text = fbAMB.Files(0) End If @@ -129,7 +129,7 @@ Public Class F_Main ' Open the filebrowser for the selection of the datafile from the calibration run Private Sub ButtonSelectDataC_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectDataC.Click ' Open the filebrowser with the *.csdat parameter - If fbVEL.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbVEL.OpenDialog(AppPreferences.workingDir, False) Then If (fbVEL.Files(0) <> Nothing) Then Me.TextBoxDataC.Text = fbVEL.Files(0) End If @@ -153,7 +153,7 @@ Public Class F_Main ' Open the filebrowser for the selection of the measure section config file (MSC) Private Sub ButtonSelectMSCC_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectMSCC.Click ' Open the filebrowser with the *.csmsc parameter - If fbMSC.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbMSC.OpenDialog(AppPreferences.workingDir, False) Then If (fbMSC.Files(0) <> Nothing) Then Me.TextBoxMSCC.Text = fbMSC.Files(0) End If @@ -235,7 +235,7 @@ Public Class F_Main ' Open the filebrowser for the selection of the measure section file from the test run Private Sub ButtonSelectMSCT_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectMSCT.Click ' Open the filebrowser with the *.csmsc parameter - If fbMSC.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbMSC.OpenDialog(AppPreferences.workingDir, False) Then If (fbMSC.Files(0) <> Nothing) Then Me.TextBoxMSCT.Text = fbMSC.Files(0) End If @@ -259,7 +259,7 @@ Public Class F_Main ' Open the filebrowser for the selection of the first low speed data file from the test run Private Sub ButtonSelectDataLS1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectDataLS1.Click ' Open the filebrowser with the *.csdat parameter - If fbVEL.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbVEL.OpenDialog(AppPreferences.workingDir, False) Then If (fbVEL.Files(0) <> Nothing) Then Me.TextBoxDataLS1.Text = fbVEL.Files(0) End If @@ -283,7 +283,7 @@ Public Class F_Main ' Open the filebrowser for the selection of the high speed data file from the test run Private Sub ButtonSelectDataHS_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectDataHS.Click ' Open the filebrowser with the *.csdat parameter - If fbVEL.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbVEL.OpenDialog(AppPreferences.workingDir, False) Then If (fbVEL.Files(0) <> Nothing) Then Me.TextBoxDataHS.Text = fbVEL.Files(0) End If @@ -307,7 +307,7 @@ Public Class F_Main ' Open the filebrowser for the selection of the second low speed data file from the test run Private Sub ButtonSelectDataLS2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectDataLS2.Click ' Open the filebrowser with the *.csdat parameter - If fbVEL.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbVEL.OpenDialog(AppPreferences.workingDir, False) Then If (fbVEL.Files(0) <> Nothing) Then Me.TextBoxDataLS2.Text = fbVEL.Files(0) End If @@ -393,7 +393,7 @@ Public Class F_Main ' Menu open Private Sub ToolStripMenuItemOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItemOpen.Click ' Open the filebrowser with the *.csjob parameter - If fbVECTO.OpenDialog(AppPreferences.WorkingDir, False) Then + If fbVECTO.OpenDialog(AppPreferences.workingDir, False) Then JobFile = fbVECTO.Files(0) If (JobFile <> Nothing) Then ' Clear the GUI @@ -566,7 +566,7 @@ Public Class F_Main '##### START THE CALCULATION ##### '################################# - calculation(Cali) + calculation(Cali) '################################# diff --git a/CSE/GUI/F_Preferences.designer.vb b/CSE/GUI/F_Preferences.designer.vb index cf3bb3ea61d437c44365b5741d0b8ed4ff04a494..de9bb90a896b1d469f7785affbd6fc09c1f6615f 100644 --- a/CSE/GUI/F_Preferences.designer.vb +++ b/CSE/GUI/F_Preferences.designer.vb @@ -23,37 +23,44 @@ Partial Class F_Preferences <System.Diagnostics.DebuggerStepThrough()> _ Private Sub InitializeComponent() Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(F_Preferences)) - Me.TextBoxWorDir = New System.Windows.Forms.TextBox() + Me.workingDir = New System.Windows.Forms.TextBox() Me.ButtonSelectWorDir = New System.Windows.Forms.Button() Me.GroupBoxWorDir = New System.Windows.Forms.GroupBox() Me.ButtonOK = New System.Windows.Forms.Button() Me.ButtonCancel = New System.Windows.Forms.Button() - Me.CheckBoxWriteLog = New System.Windows.Forms.CheckBox() + Me.writeLog = New System.Windows.Forms.CheckBox() Me.GroupBoxInterface = New System.Windows.Forms.GroupBox() Me.LabelInfo = New System.Windows.Forms.Label() - Me.TextBoxLogSize = New System.Windows.Forms.TextBox() + Me.logSize = New System.Windows.Forms.TextBox() Me.Label16 = New System.Windows.Forms.Label() Me.Label1 = New System.Windows.Forms.Label() - Me.TextBoxMSG = New System.Windows.Forms.TextBox() + Me.logLevel = New System.Windows.Forms.TextBox() Me.TabControl1 = New System.Windows.Forms.TabControl() Me.TabPage2 = New System.Windows.Forms.TabPage() Me.GroupBoxNotepad = New System.Windows.Forms.GroupBox() Me.ButtonSelectNotepad = New System.Windows.Forms.Button() - Me.TextBoxNotepad = New System.Windows.Forms.TextBox() + Me.editor = New System.Windows.Forms.TextBox() + Me.GroupBox1 = New System.Windows.Forms.GroupBox() + 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.GroupBoxWorDir.SuspendLayout() Me.GroupBoxInterface.SuspendLayout() Me.TabControl1.SuspendLayout() Me.TabPage2.SuspendLayout() Me.GroupBoxNotepad.SuspendLayout() + Me.GroupBox1.SuspendLayout() Me.SuspendLayout() ' - 'TextBoxWorDir + 'workingDir ' - Me.TextBoxWorDir.Location = New System.Drawing.Point(6, 19) - Me.TextBoxWorDir.Name = "TextBoxWorDir" - Me.TextBoxWorDir.Size = New System.Drawing.Size(444, 20) - Me.TextBoxWorDir.TabIndex = 1 + Me.workingDir.Location = New System.Drawing.Point(6, 19) + Me.workingDir.Name = "workingDir" + Me.workingDir.Size = New System.Drawing.Size(444, 20) + Me.workingDir.TabIndex = 1 ' 'ButtonSelectWorDir ' @@ -68,7 +75,7 @@ Partial Class F_Preferences 'GroupBoxWorDir ' Me.GroupBoxWorDir.Controls.Add(Me.ButtonSelectWorDir) - Me.GroupBoxWorDir.Controls.Add(Me.TextBoxWorDir) + Me.GroupBoxWorDir.Controls.Add(Me.workingDir) Me.GroupBoxWorDir.Location = New System.Drawing.Point(5, 6) Me.GroupBoxWorDir.Name = "GroupBoxWorDir" Me.GroupBoxWorDir.Size = New System.Drawing.Size(490, 51) @@ -79,7 +86,8 @@ Partial Class F_Preferences 'ButtonOK ' Me.ButtonOK.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) - Me.ButtonOK.Location = New System.Drawing.Point(436, 235) + Me.ButtonOK.DialogResult = System.Windows.Forms.DialogResult.OK + Me.ButtonOK.Location = New System.Drawing.Point(436, 242) Me.ButtonOK.Name = "ButtonOK" Me.ButtonOK.Size = New System.Drawing.Size(75, 23) Me.ButtonOK.TabIndex = 0 @@ -90,78 +98,78 @@ Partial Class F_Preferences ' 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, 235) + Me.ButtonCancel.Location = New System.Drawing.Point(99, 242) Me.ButtonCancel.Name = "ButtonCancel" Me.ButtonCancel.Size = New System.Drawing.Size(75, 23) Me.ButtonCancel.TabIndex = 1 Me.ButtonCancel.Text = "Cancel" Me.ButtonCancel.UseVisualStyleBackColor = True ' - 'CheckBoxWriteLog + 'writeLog ' - Me.CheckBoxWriteLog.AutoSize = True - Me.CheckBoxWriteLog.Location = New System.Drawing.Point(353, 15) - Me.CheckBoxWriteLog.Name = "CheckBoxWriteLog" - Me.CheckBoxWriteLog.Size = New System.Drawing.Size(129, 17) - Me.CheckBoxWriteLog.TabIndex = 5 - Me.CheckBoxWriteLog.Text = "Write log file (LOG.txt)" - Me.CheckBoxWriteLog.UseVisualStyleBackColor = True + Me.writeLog.AutoSize = True + Me.writeLog.Location = New System.Drawing.Point(13, 58) + Me.writeLog.Name = "writeLog" + Me.writeLog.Size = New System.Drawing.Size(108, 17) + Me.writeLog.TabIndex = 2 + Me.writeLog.Text = "Log-file Enabled?" + Me.writeLog.UseVisualStyleBackColor = True ' 'GroupBoxInterface ' Me.GroupBoxInterface.Controls.Add(Me.LabelInfo) - Me.GroupBoxInterface.Controls.Add(Me.TextBoxLogSize) + Me.GroupBoxInterface.Controls.Add(Me.logSize) Me.GroupBoxInterface.Controls.Add(Me.Label16) Me.GroupBoxInterface.Controls.Add(Me.Label1) - Me.GroupBoxInterface.Controls.Add(Me.TextBoxMSG) - Me.GroupBoxInterface.Controls.Add(Me.CheckBoxWriteLog) + Me.GroupBoxInterface.Controls.Add(Me.logLevel) + Me.GroupBoxInterface.Controls.Add(Me.writeLog) Me.GroupBoxInterface.Location = New System.Drawing.Point(5, 120) Me.GroupBoxInterface.Name = "GroupBoxInterface" - Me.GroupBoxInterface.Size = New System.Drawing.Size(490, 75) + Me.GroupBoxInterface.Size = New System.Drawing.Size(341, 84) Me.GroupBoxInterface.TabIndex = 11 Me.GroupBoxInterface.TabStop = False - Me.GroupBoxInterface.Text = "Interface" + Me.GroupBoxInterface.Text = "Logging && Messages" ' 'LabelInfo ' Me.LabelInfo.AutoSize = True - Me.LabelInfo.Location = New System.Drawing.Point(185, 22) + Me.LabelInfo.Location = New System.Drawing.Point(154, 22) Me.LabelInfo.Name = "LabelInfo" Me.LabelInfo.Size = New System.Drawing.Size(39, 13) Me.LabelInfo.TabIndex = 12 Me.LabelInfo.Text = "Label2" ' - 'TextBoxLogSize + 'logSize ' - Me.TextBoxLogSize.Location = New System.Drawing.Point(440, 38) - Me.TextBoxLogSize.Name = "TextBoxLogSize" - Me.TextBoxLogSize.Size = New System.Drawing.Size(36, 20) - Me.TextBoxLogSize.TabIndex = 11 + Me.logSize.Location = New System.Drawing.Point(299, 55) + Me.logSize.Name = "logSize" + Me.logSize.Size = New System.Drawing.Size(36, 20) + Me.logSize.TabIndex = 3 ' 'Label16 ' Me.Label16.AutoSize = True - Me.Label16.Location = New System.Drawing.Point(356, 41) + Me.Label16.Location = New System.Drawing.Point(181, 59) Me.Label16.Name = "Label16" - Me.Label16.Size = New System.Drawing.Size(78, 13) + Me.Label16.Size = New System.Drawing.Size(112, 13) Me.Label16.TabIndex = 10 - Me.Label16.Text = "Size Limit [MiB]" + Me.Label16.Text = "Log-file size limit [MiB]:" ' 'Label1 ' Me.Label1.AutoSize = True - Me.Label1.Location = New System.Drawing.Point(27, 22) + Me.Label1.Location = New System.Drawing.Point(10, 22) Me.Label1.Name = "Label1" - Me.Label1.Size = New System.Drawing.Size(110, 13) + Me.Label1.Size = New System.Drawing.Size(96, 13) Me.Label1.TabIndex = 7 - Me.Label1.Text = "Output Window Level" + Me.Label1.Text = "Log-window Level:" ' - 'TextBoxMSG + 'logLevel ' - Me.TextBoxMSG.Location = New System.Drawing.Point(143, 19) - Me.TextBoxMSG.Name = "TextBoxMSG" - Me.TextBoxMSG.Size = New System.Drawing.Size(36, 20) - Me.TextBoxMSG.TabIndex = 6 + Me.logLevel.Location = New System.Drawing.Point(112, 19) + Me.logLevel.Name = "logLevel" + Me.logLevel.Size = New System.Drawing.Size(36, 20) + Me.logLevel.TabIndex = 1 ' 'TabControl1 ' @@ -172,18 +180,19 @@ Partial Class F_Preferences Me.TabControl1.Location = New System.Drawing.Point(3, 3) Me.TabControl1.Name = "TabControl1" Me.TabControl1.SelectedIndex = 0 - Me.TabControl1.Size = New System.Drawing.Size(508, 226) + Me.TabControl1.Size = New System.Drawing.Size(508, 233) Me.TabControl1.TabIndex = 12 ' 'TabPage2 ' Me.TabPage2.Controls.Add(Me.GroupBoxNotepad) Me.TabPage2.Controls.Add(Me.GroupBoxWorDir) + Me.TabPage2.Controls.Add(Me.GroupBox1) Me.TabPage2.Controls.Add(Me.GroupBoxInterface) Me.TabPage2.Location = New System.Drawing.Point(4, 22) Me.TabPage2.Name = "TabPage2" Me.TabPage2.Padding = New System.Windows.Forms.Padding(3) - Me.TabPage2.Size = New System.Drawing.Size(500, 200) + Me.TabPage2.Size = New System.Drawing.Size(500, 207) Me.TabPage2.TabIndex = 0 Me.TabPage2.Text = "General" Me.TabPage2.UseVisualStyleBackColor = True @@ -191,7 +200,7 @@ Partial Class F_Preferences 'GroupBoxNotepad ' Me.GroupBoxNotepad.Controls.Add(Me.ButtonSelectNotepad) - Me.GroupBoxNotepad.Controls.Add(Me.TextBoxNotepad) + Me.GroupBoxNotepad.Controls.Add(Me.editor) Me.GroupBoxNotepad.Location = New System.Drawing.Point(5, 63) Me.GroupBoxNotepad.Name = "GroupBoxNotepad" Me.GroupBoxNotepad.Size = New System.Drawing.Size(490, 51) @@ -209,17 +218,77 @@ Partial Class F_Preferences Me.ButtonSelectNotepad.Text = "..." Me.ButtonSelectNotepad.UseVisualStyleBackColor = True ' - 'TextBoxNotepad - ' - Me.TextBoxNotepad.Location = New System.Drawing.Point(6, 19) - Me.TextBoxNotepad.Name = "TextBoxNotepad" - Me.TextBoxNotepad.Size = New System.Drawing.Size(444, 20) - Me.TextBoxNotepad.TabIndex = 1 + 'editor + ' + Me.editor.Location = New System.Drawing.Point(6, 19) + Me.editor.Name = "editor" + Me.editor.Size = New System.Drawing.Size(444, 20) + Me.editor.TabIndex = 1 + ' + 'GroupBox1 + ' + Me.GroupBox1.Controls.Add(Me.strictBodies) + Me.GroupBox1.Controls.Add(Me.includeSchemas) + Me.GroupBox1.Controls.Add(Me.TextBox1) + Me.GroupBox1.Controls.Add(Me.Label3) + Me.GroupBox1.Controls.Add(Me.CheckBox1) + Me.GroupBox1.Location = New System.Drawing.Point(352, 120) + Me.GroupBox1.Name = "GroupBox1" + Me.GroupBox1.Size = New System.Drawing.Size(152, 84) + Me.GroupBox1.TabIndex = 11 + Me.GroupBox1.TabStop = False + Me.GroupBox1.Text = "JSON" + ' + 'strictBodies + ' + Me.strictBodies.AutoSize = True + Me.strictBodies.Location = New System.Drawing.Point(6, 57) + Me.strictBodies.Name = "strictBodies" + Me.strictBodies.Size = New System.Drawing.Size(91, 17) + Me.strictBodies.TabIndex = 12 + Me.strictBodies.Text = "Strict Bodies?" + Me.strictBodies.UseVisualStyleBackColor = True + ' + 'includeSchemas + ' + Me.includeSchemas.AutoSize = True + Me.includeSchemas.Location = New System.Drawing.Point(6, 21) + Me.includeSchemas.Name = "includeSchemas" + Me.includeSchemas.Size = New System.Drawing.Size(114, 17) + Me.includeSchemas.TabIndex = 12 + Me.includeSchemas.Text = "Include Schemas?" + Me.includeSchemas.UseVisualStyleBackColor = True + ' + 'TextBox1 + ' + Me.TextBox1.Location = New System.Drawing.Point(440, 38) + Me.TextBox1.Name = "TextBox1" + Me.TextBox1.Size = New System.Drawing.Size(36, 20) + Me.TextBox1.TabIndex = 11 + ' + 'Label3 + ' + Me.Label3.AutoSize = True + Me.Label3.Location = New System.Drawing.Point(356, 41) + Me.Label3.Name = "Label3" + Me.Label3.Size = New System.Drawing.Size(78, 13) + Me.Label3.TabIndex = 10 + Me.Label3.Text = "Size Limit [MiB]" + ' + 'CheckBox1 + ' + Me.CheckBox1.AutoSize = True + Me.CheckBox1.Location = New System.Drawing.Point(353, 15) + Me.CheckBox1.Name = "CheckBox1" + Me.CheckBox1.Size = New System.Drawing.Size(129, 17) + Me.CheckBox1.TabIndex = 5 + Me.CheckBox1.Text = "Write log file (LOG.txt)" + Me.CheckBox1.UseVisualStyleBackColor = True ' 'ButtonReload ' Me.ButtonReload.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) - Me.ButtonReload.Location = New System.Drawing.Point(18, 235) + Me.ButtonReload.Location = New System.Drawing.Point(18, 242) Me.ButtonReload.Name = "ButtonReload" Me.ButtonReload.Size = New System.Drawing.Size(75, 23) Me.ButtonReload.TabIndex = 0 @@ -232,7 +301,7 @@ Partial Class F_Preferences Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.CancelButton = Me.ButtonCancel - Me.ClientSize = New System.Drawing.Size(515, 270) + Me.ClientSize = New System.Drawing.Size(515, 277) Me.Controls.Add(Me.TabControl1) Me.Controls.Add(Me.ButtonCancel) Me.Controls.Add(Me.ButtonReload) @@ -252,25 +321,33 @@ Partial Class F_Preferences Me.TabPage2.ResumeLayout(False) Me.GroupBoxNotepad.ResumeLayout(False) Me.GroupBoxNotepad.PerformLayout() + Me.GroupBox1.ResumeLayout(False) + Me.GroupBox1.PerformLayout() Me.ResumeLayout(False) End Sub - Friend WithEvents TextBoxWorDir As System.Windows.Forms.TextBox + Friend WithEvents workingDir As System.Windows.Forms.TextBox Friend WithEvents ButtonSelectWorDir As System.Windows.Forms.Button Friend WithEvents GroupBoxWorDir As System.Windows.Forms.GroupBox Friend WithEvents ButtonOK As System.Windows.Forms.Button Friend WithEvents ButtonCancel As System.Windows.Forms.Button - Friend WithEvents CheckBoxWriteLog As System.Windows.Forms.CheckBox + Friend WithEvents writeLog As System.Windows.Forms.CheckBox Friend WithEvents GroupBoxInterface As System.Windows.Forms.GroupBox Friend WithEvents TabControl1 As System.Windows.Forms.TabControl Friend WithEvents TabPage2 As System.Windows.Forms.TabPage Friend WithEvents Label1 As System.Windows.Forms.Label - Friend WithEvents TextBoxMSG As System.Windows.Forms.TextBox - Friend WithEvents TextBoxLogSize As System.Windows.Forms.TextBox + Friend WithEvents logLevel As System.Windows.Forms.TextBox + Friend WithEvents logSize As System.Windows.Forms.TextBox Friend WithEvents Label16 As System.Windows.Forms.Label Friend WithEvents GroupBoxNotepad As System.Windows.Forms.GroupBox Friend WithEvents ButtonSelectNotepad As System.Windows.Forms.Button - Friend WithEvents TextBoxNotepad As System.Windows.Forms.TextBox + Friend WithEvents editor As System.Windows.Forms.TextBox Friend WithEvents LabelInfo As System.Windows.Forms.Label Friend WithEvents ButtonReload As System.Windows.Forms.Button + Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox + Friend WithEvents TextBox1 As System.Windows.Forms.TextBox + Friend WithEvents Label3 As System.Windows.Forms.Label + Friend WithEvents CheckBox1 As System.Windows.Forms.CheckBox + Friend WithEvents strictBodies As System.Windows.Forms.CheckBox + Friend WithEvents includeSchemas As System.Windows.Forms.CheckBox End Class diff --git a/CSE/GUI/F_Preferences.vb b/CSE/GUI/F_Preferences.vb index c1f7094b555f5f1230918620a4d19ac4423c1b15..3af4a18bb7e9506703fe53f60199ea0a9ddd107c 100644 --- a/CSE/GUI/F_Preferences.vb +++ b/CSE/GUI/F_Preferences.vb @@ -1,36 +1,56 @@ +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 - ' Allocate the data from the confic file (Only by the start) - UI_PopulateFrom(AppPreferences) + Dim controlPairs As IList(Of Control()) = New List(Of Control()) + '' CONTROL LABEL + controlPairs.Add({Me.workingDir, Me.GroupBoxWorDir}) + controlPairs.Add({Me.editor, Me.GroupBoxNotepad}) + controlPairs.Add({Me.writeLog, Nothing}) + controlPairs.Add({Me.logLevel, Label1}) + controlPairs.Add({Me.logSize, Label16}) + controlPairs.Add({Me.includeSchemas, Nothing}) + controlPairs.Add({Me.strictBodies, Nothing}) + + '' Add help-tooltips from Json-Schema. + '' + Dim schema = JObject.Parse(cPreferences.JSchemaStr) + For Each row In controlPairs + Dim ctrl = row(0) + Dim Label = row(1) + updateControlsFromSchema(schema, ctrl, Label) + Next - ' Define the Infolable - TextBoxMSG_TextChanged(sender, e) + UI_PopulateFrom(AppPreferences) End Sub Private Sub UI_PopulateFrom(ByVal value As cPreferences) ' Allocate the data from the confic file (Only by the start) - Me.TextBoxWorDir.Text = value.WorkingDir - Me.TextBoxNotepad.Text = value.Editor - Me.CheckBoxWriteLog.Checked = value.WriteLog - Me.TextBoxMSG.Text = value.LogLevel - Me.TextBoxLogSize.Text = value.LogSize + 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.strictBodies.Checked = value.StrictBodies End Sub Private Sub UI_PopulateTo(ByVal value As cPreferences) - value.WorkingDir = Me.TextBoxWorDir.Text - value.Editor = Me.TextBoxNotepad.Text - value.WriteLog = Me.CheckBoxWriteLog.Checked - value.LogLevel = Me.TextBoxMSG.Text - value.LogSize = Me.TextBoxLogSize.Text - + 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.StrictBodies = Me.strictBodies.Checked End Sub ' Open the filebrowser for selecting the working dir Private Sub ButtonWorDir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectWorDir.Click - If fbWorkDir.OpenDialog(Me.TextBoxWorDir.Text) Then - Me.TextBoxWorDir.Text = fbWorkDir.Files(0) + If fbWorkDir.OpenDialog(Me.workingDir.Text) Then + Me.workingDir.Text = fbWorkDir.Files(0) End If End Sub @@ -46,10 +66,11 @@ Public Class F_Preferences ' Message for the restart of VECTO RestartN = True - fInfWarErr(7, False, "Preferences have changed. Ask to restart.") - fInfWarErr(7, True, format("Preferences have changed.\nDo you want to restart VECTO now?")) + fInfWarErr(7, False, format("Stored Preferences({0}).", PreferencesPath)) + fInfWarErr(7, True, format("Stored Preferences({0}). \n\nDo you want to restart VECTO now?", PreferencesPath)) Catch ex As Exception - fInfWarErr(9, False, format("Failed storing Preferences({0}) due to: {1} \n Preferences left unmodified!", PreferencesPath, ex.Message), ex) + fInfWarErr(9, False, format("Failed storing Preferences({0}) due to: {1} \n Preferences left unmodified!", _ + PreferencesPath, ex.Message), ex) End Try ' Close the window @@ -61,9 +82,6 @@ Public Class F_Preferences Try AppPreferences = New cPreferences(PreferencesPath) UI_PopulateFrom(AppPreferences) - - ' Define the Infolable - TextBoxMSG_TextChanged(sender, e) Catch ex As Exception fInfWarErr(9, False, format("Failed loading Preferences({0}) due to: {1}", _ PreferencesPath, ex.Message), ex) @@ -77,13 +95,13 @@ Public Class F_Preferences ' Select the Notepad path Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSelectNotepad.Click - If fbExe.OpenDialog(Me.TextBoxWorDir.Text) Then - Me.TextBoxNotepad.Text = fbExe.Files(0) + If fbExe.OpenDialog(Me.workingDir.Text) Then + Me.editor.Text = fbExe.Files(0) End If End Sub ' Interception from kyepress events in the MSG box - Private Sub TextBoxMSG_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBoxMSG.KeyPress + Private Sub TextBoxMSG_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles logLevel.KeyPress Select Case Asc(e.KeyChar) Case 48 To 56, 8 ' Numbers from 1 till 8 allowed (ASCII) Case Else ' Eliminate all other inputs @@ -92,13 +110,13 @@ Public Class F_Preferences End Sub ' Set the MSG box to default if it is leave without an input - Private Sub TextBoxMSG_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBoxMSG.Leave - If Me.TextBoxMSG.Text = Nothing Then Me.TextBoxMSG.Text = 5 + Private Sub TextBoxMSG_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles logLevel.Leave + If Me.logLevel.Text = Nothing Then Me.logLevel.Text = 5 End Sub ' Changes in the MSG --> Change the lable - Private Sub TextBoxMSG_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBoxMSG.TextChanged - Select Case Me.TextBoxMSG.Text + Private Sub TextBoxMSG_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles logLevel.TextChanged + Select Case Me.logLevel.Text Case 0 To 2 ' Show all Me.LabelInfo.Text = "All" Case 3 ' No infos with priority 5 (*) @@ -117,7 +135,7 @@ Public Class F_Preferences End Sub ' Changes in the LogSizeBox - Private Sub TextBoxLogSize_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBoxLogSize.KeyPress + Private Sub TextBoxLogSize_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles logSize.KeyPress, TextBox1.KeyPress Select Case Asc(e.KeyChar) Case 48 To 58, 8 ' Numbers allowed (ASCII) Case Else ' Eliminate all other input data @@ -126,12 +144,8 @@ Public Class F_Preferences End Sub ' Set the LogSize to default if it is leave without an input - Private Sub TextBoxLogSize_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBoxLogSize.Leave - If Me.TextBoxLogSize.Text = Nothing Then Me.TextBoxLogSize.Text = 2 - End Sub - - Private Sub GroupBoxWorDir_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GroupBoxWorDir.Enter - + 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 = 2 End Sub End Class diff --git a/CSE/GUI/minor_routines_GUI.vb b/CSE/GUI/minor_routines_GUI.vb index 35fb5bfe3326b17e964c35a095305e41375aac87..608e5e3f514c0d30c52d776e68d6801d0e8479fe 100644 --- a/CSE/GUI/minor_routines_GUI.vb +++ b/CSE/GUI/minor_routines_GUI.vb @@ -1,4 +1,6 @@ -Module minor_routines_GUI +Imports Newtonsoft.Json.Linq + +Module minor_routines_GUI ' Clear the GUI Public Function fClear_VECTO_Form(ByVal Komplet As Boolean, Optional ByVal Fields As Boolean = True) As Boolean @@ -579,4 +581,97 @@ End Function -End Module \ No newline at end of file + Sub updateControlsFromSchema(ByVal schema As JObject, ByVal ctrl As Control, ByVal label As Control) + Try + Dim pschema = schema.SelectToken(".properties." & ctrl.Name) + If pschema Is Nothing Then + fInfWarErr(8, False, format("Schema2GUI: Could not find schema for Control({0})!\n\iSchema: {1}", ctrl.Name, schema)) + Return + End If + + '' Set title on control/label + '' + Dim title = pschema("title") + If title IsNot Nothing Then + If label IsNot Nothing Then + label.Text = title + Else + If TypeOf ctrl Is CheckBox Then + title = title.ToString() & "?" + End If + End If + ctrl.Text = title + End If + + '' Build tooltip. + '' + Dim infos = _ + From pname In {"title", "description", "type", "enum", "default", _ + "minimum", "exclusiveMinimum", "maximum", "exclusiveMaximum"} + Select pschema(pname) + + ''TODO: Include other schema-props in tooltips. + + If infos.Any() Then + Dim msg = schemaInfos2helpMsg(infos.ToArray()) + Dim t = New ToolTip() + t.SetToolTip(ctrl, msg) + t.AutomaticDelay = 300 + t.AutoPopDelay = 10000 + End If + + + Catch ex As Exception + fInfWarErr(8, False, format("Schema2GUI: Skipped exception: {0} ", ex.Message), ex) + End Try + End Sub + + ''' <summary>Builds a human-readable help-string from any non-null schema-properties.</summary> + Function schemaInfos2helpMsg(ByVal ParamArray propSchemaInfos() As JToken) As String + Dim titl = propSchemaInfos(0) + Dim desc = propSchemaInfos(1) + Dim type = propSchemaInfos(2) + Dim chce = propSchemaInfos(3) + Dim dflt = propSchemaInfos(4) + Dim mini = propSchemaInfos(5) + Dim miex = propSchemaInfos(6) '' exclusiveMin + Dim maxi = propSchemaInfos(7) + Dim maex = propSchemaInfos(8) '' exclusiveMax + + Dim sdesc As String = "" + Dim stype As String = "" + Dim senum As String = "" + Dim sdflt As String = "" + Dim slimt As String = "" + + If desc IsNot Nothing Then + sdesc = format(desc.ToString()) + ElseIf titl IsNot Nothing Then + sdesc = format(titl.ToString()) + End If + If type IsNot Nothing Then stype = type.ToString(Newtonsoft.Json.Formatting.None) & ": " + If chce IsNot Nothing Then senum = format("\n- choices: {0}", chce.ToString(Newtonsoft.Json.Formatting.None)) + If dflt IsNot Nothing Then sdflt = format("\n- default: {0}", dflt) + If mini IsNot Nothing OrElse maxi IsNot Nothing Then + Dim infinitySymbol = "" + ChrW(&H221E) + Dim open = "("c + Dim smin = infinitySymbol + Dim smax = infinitySymbol + Dim clos = ")"c + + If mini IsNot Nothing Then + smin = mini + If (miex Is Nothing OrElse Not CBool(miex)) Then open = "["c + End If + If maxi IsNot Nothing Then + smax = maxi + If (maex Is Nothing OrElse Not CBool(maex)) Then clos = "]"c + End If + slimt = format("\n- limits : {0}{1}, {2}{3}", _ + open, smin, smax, clos) + End If + + Return String.Join("", stype, sdesc, senum, sdflt, slimt) + End Function + +End Module