diff --git a/CHANGELOG.md b/CHANGELOG.md index 492f568..47e1dc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,32 @@ GitHub Release. Entries before this file existed were reconstructed from those release tags. +## [1.40.0] — 2026-10-17 + +More numbers and classes read from a `.mat` file or a model workspace now match MATLAB and the dictionaries. A number inside an object, such as a Simulink.Parameter's Value, keeps its class: `int32([100 200 300 400])` shows class `int32` and a logical row shows `logical`, where both showed `double`, and an `int64` or `uint64` at the end of its range, such as `18446744073709551615`, shows as a number where it showed in quotes as text. A `single` shows the digits MATLAB writes into a dictionary, such as `3.3` and `[1.1 2.2 3.3]`, where it showed `3.299999952316284` and `[1.100000023841858 2.200000047683716 3.299999952316284]`, inside an object or not. A Parameter copied out of a `.mat` file into a dictionary keeps its Value's class; before, an `int8` -42 was pasted into a binary dictionary as the double `-42.0`. An array of objects of more than one class, held inside an object, takes the class MATLAB records for the array, and each element keeps its own: an array of a Simulink.Signal subclass and a Simulink.Signal shows as `<1x2 Simulink.Signal>`, where both elements showed as the subclass, and a configuration set's Components show in the Properties panel as `<9x1 Simulink.ConfigComponent>`, the class MATLAB gives them. Before, every element took the first one's class, so a configuration set copied into a dictionary was written with every one of its components as a Simulink.SolverCC. + +In a binary dictionary, the Properties panel's Other group shows a nested object's own properties, as it already did for a `.mat` file: a Simulink.LookupTable's Table and Breakpoints list their Value, such as `[1+2i, 3+4i, 5+6i]`, their Dimensions, Data Type and the rest, as they already did in a JSON dictionary, and a Simulink.Signal's LoggingInfo lists its seven settings, where each was one empty row. In a JSON dictionary too, a bus with a single element now lists that element's properties there, where it was one empty row. In every kind of file, a nested array of more than one object shows its size and class there, such as `<2x1 Simulink.BusElement>` for a bus's elements, where it was empty. + +A Simulink.Signal's Complexity and Dimensions Mode, and an mpt.Signal's, are now dropdowns in the table, offering MATLAB's choices (`auto`, `real` or `complex`; `auto`, `Fixed` or `Variable`), as a bus element's already were; before, both were read-only. These columns, like Storage Class and Alignment below, are hidden by default: show them from the column menu. A Signal left at `auto`, or set back to it, is saved as MATLAB saves it, with no key added in a JSON dictionary. A Simulink.Parameter's or Simulink.Signal's Alignment, and an mpt subclass's, can now be edited in the table when its Storage Class is not `Auto`, by MATLAB's rule: `-1`, or a power of two from 1 to 2^30. A value is first rounded as MATLAB's `int32` rounds it, so `1.5` sets `2`, and any value that is then neither is refused with MATLAB's message, such as `3 is not a valid alignment boundary. The alignment boundary must be either -1 or a power of two.`, and nothing changes. An accepted value is saved as MATLAB saves it. Setting the Storage Class to `Auto` resets Alignment to `-1`, as MATLAB does. Before, Alignment could not be edited at all. + +Cells for five properties that MATLAB's classes do not have no longer open an editor. Before, a Simulink.LookupTable's or Simulink.Breakpoint's Description could be typed and saved, though MATLAB ignores it; a Simulink.VariantControl's Description was shown and then dropped on save; and a Simulink.VariantBank's or Simulink.VariantBankCoderInfo's Value was saved into the file, where MATLAB ignores it. One that a LookupTable, Breakpoint, VariantBank or VariantBankCoderInfo already has in its file is shown read-only and saved unchanged, and a VariantBank or VariantBankCoderInfo written by MATLAB shows an empty Value, where it showed `''`. Clearing a Simulink.VariantVariable's Specification now clears it in the saved file, as MATLAB clears it. Before, if this extension had set and saved the Specification, clearing it and saving again left the old value in the file, and it came back on reopening, in MATLAB too. This affected VariantVariables in binary dictionaries, and those this extension created in JSON dictionaries. + +A dictionary that holds two entries with the same name in one section, which only a damaged or hand-edited file does, now opens with a banner saying so, such as `Two entries in Design Data are named 'gravity'. Neither can be edited or deleted until the file gives one of them another name.`, and an edit or a delete of either one is refused, leaving the file as it was. Before, nothing said the names were shared, and an edit or a delete of one entry could change or remove the other. + +An mpt.Parameter or mpt.Signal entry can now be pasted or dropped into a dictionary's Design Data, from a JSON or a binary dictionary into either, and keeps its class; before, Paste and the drop refused it there. New mpt entries still cannot be created from the Add gallery. Dragging entries from two sections onto one of them now moves them there, as cutting and pasting them already did; before, the drop could be refused without a message. With two section headers selected, or a header and an entry from another section, Paste is now disabled, with the tooltip `Select rows in one section to paste`, and Ctrl+V or Cmd+V does nothing. Before, Paste stayed enabled, and the context menu pasted into the right-clicked row's section while Ctrl+V or Cmd+V pasted into the first selected row's, so one selection could paste into two different places. A lone header still pastes into its section, and so does a header selected with its own section's entries. Because a selected header now counts, Paste is also disabled after Ctrl+A or Cmd+A, even when only one section holds entries. + +Every top-level name in a file now gets a row. Before, a file with more than 100,000 of them, counting every section's entries together, showed only about the first 100,000 and a banner saying the rest existed: on a 291,564-entry dictionary, 191,568 names had no row. A cell array with more than 100,000 elements lost its tail the same way when it was opened. In a file with more names than that, each row loads its contents when it is expanded. Only if the view cannot take the rows at all does it show the first 100,000, with a banner saying so. Closing a file's last tab now releases the parsed copy the tab held; before, every file opened stayed parsed until the window closed, about 67 MB for a 20 MB dictionary. When the table updates while a cell is being edited, such as after a save or an edit in the text view, and the update removes that cell's row or column, the editor now closes without writing anything, and the keyboard keeps working. Before, the editor disappeared but the table went on ignoring every key. An update that keeps the row and the column leaves the editor open with what was typed, as before. + +A model that references one model from two Model blocks now shows two Model References rows that can each be selected on its own, and the Properties panel shows each one's own Block Path. Before, clicking either one selected both, and the Properties panel showed the second block's path for both. Two External Data rows for files with one name in different folders, such as `a/signals.mat` and `b/signals.mat`, are told apart the same way, each with its own Path. + +If columns that are hidden by default, such as Last Modified By, appeared in your table after an update, Reset to default in the column menu hides them again, restoring the default layout. From this version on, a column a later version adds hidden by default starts hidden, even after you have changed the column layout. The Status column's Modified mark now takes the theme's colour for a modified file, the one the Data Explorer tree's Modified badge uses, so it meets WCAG AA's 4.5:1 contrast on dark and high-contrast themes; before, it measured 3.54:1 on Dark Modern and 4.18:1 on High Contrast Black. It was one fixed colour in every theme, and still is where the theme colour is not defined, such as with VS Code's built-in Git extension disabled. The tooltip on the Add gallery's Keep open checkbox no longer says that closing the gallery selects every entry added, which it never did. It now reads `Stay open after each add. Entries land immediately and are not renamed.`, and closing still selects the last entry added. + +An open JSON dictionary's or `.mat` file's Usage column now updates when a model that uses it is created or deleted in the workspace, such as by a branch switch; before, it kept showing the old usage until the file was edited, saved or reopened. A model changed on disk still does not update it until you do one of those. For a model whose model workspace is loaded from a `.mat` file, Usage now looks in that file before the model's dictionary, as MATLAB does. So for a name both define, the `.mat` variable's Usage names the blocks that use it and the dictionary entry's no longer does; before, it was the other way round. A link that names a file only by its name, such as a Model Reference or an External Data link, now opens the copy in the same project or folder as the file the link is in when the workspace holds more than one file of that name, as the Data Explorer tree does, whether it is clicked in a table or in the Properties panel; before, it opened whichever copy the workspace search found first. When a file in the workspace is replaced by a write that keeps its modification time and size, such as restoring it from a zip or tar archive, the Data Explorer tree, Search Data Source Entries and the Usage column now follow the new contents; before, they could keep the old contents until the window was reloaded. A write that puts back the exact sub-second time the file had is still not seen, because VS Code does not report it. + +More damaged files now open with what could be read, and a warning says what could not, though in a model's workspace some damaged values show as not decoded with no warning. A `.mat` file or a model with a variable whose type information is damaged no longer fails to open with `Cannot read properties of null (reading 're')`: that variable shows as not decoded with its own size, such as `<1x1 unknown, not decoded>`, and the rest of the file opens as usual. A value nested more than 128 levels deep is read down to that depth and shown as not decoded below it; before, one nested about 1,500 levels deep stopped a `.mat` file opening with `Maximum call stack size exceeded`, left a model's workspace section empty, and showed in a JSON dictionary as a long char row, such as `<1x320033 char>`. A hand-edited model whose list of configuration sets or of model references holds a single item instead of a list now opens. If the list is malformed in any other way, or an item in it has no name, the model now opens with a warning for what was skipped. Before, most of these stopped the model opening, and the rest were read as an empty list with no warning. A model whose zip archive holds a part larger than the size the archive's own index records for it now opens without that part, with a warning naming it, so a model whose workspace part is damaged this way opens with an empty workspace section. Before, the part was silently cut at the recorded size: in one model, five of its seven workspace variables showed `[ ]` where the file holds values such as `11-12i`. + +More values that could not be read are no longer shown as if they had been. In a `.mat` file, a struct array with a damaged field in one of its elements shows as not decoded, such as `<1x3 struct, not decoded>`, with a warning; before, that field's later values moved up onto earlier elements, so element 3's value showed as element 2's. A number whose data is missing from the file shows as not decoded, such as `<2x3 double, not decoded>`, and cannot be edited, in any kind of file, and a `.mat` file also names it in a warning; before, it showed `null` or `[null]` and could be edited. When a MATLAB object's stored data is damaged part-way, in a `.mat` file, a model workspace or a dictionary, a warning now names the variable that was read only in part. The objects after the damage still show their class's defaults rather than their own values; before, nothing said so. In a `.mat` file or a model workspace, an object whose stored data cannot be matched to an object of its class shows as its class alone, such as `<1x1 Simulink.Parameter>`, with a warning that it could not be decoded. Before, it showed as an empty object of that class, such as a Parameter with Value `[ ]` and Data Type `auto` that is not the one in the file, and copying it carried that empty Parameter. A value in a JSON dictionary stored as a MATLAB data stream that does not decode is named in a warning and can no longer be edited; it still shows as its encoded text and is saved unchanged, where before nothing said it had not been read. A System Composer definition whose type is missing from the file is now named in a warning, because its Kind column then falls back to its Simulink class and may be wrong. Before, a struct type in that state showed as a Data Interface with no warning. This version ships `data-explorer-core` 1.40.0. + ## [1.39.0] — 2026-10-16 Renaming a function element of a service interface now also renames the function in System Composer's list of the interface's functions, in a JSON dictionary and in a binary dictionary alike. The dictionary records the function twice, as the function element the table shows and in that list, and only the first was renamed. Before, renaming `f`, with Prototype `y = f(u)`, to `compute` changed the function element to `compute` and `y = compute(u)`, but System Composer's list still said `f` and `y = f(u)`, so the saved file disagreed with itself about the function's name. MATLAB opened such a file without a warning, but the first read of the interface's functions after `systemcomposer.openDictionary` still named `f`, and reading their arguments gave the error `Invalid or deleted object`; only a second read named `compute`. Now both are renamed together, also when the interface was renamed first and when a function renamed in this version is renamed again, and after the rename the first read names `compute`. Undo restores both, in one step. As before, a rename whose Prototype cannot follow is refused, with a message saying why, and changes nothing. A dictionary saved this way by an earlier version keeps the old name in System Composer's list, and renaming the function again does not change it; to repair one, rename the function back to its old name and then to the new one. This version ships `data-explorer-core` 1.39.0. diff --git a/package-lock.json b/package-lock.json index bcc70f1..47f0dd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "simulink-data-explorer", - "version": "1.39.0", + "version": "1.40.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "simulink-data-explorer", - "version": "1.39.0", + "version": "1.40.0", "license": "BSD-3-Clause", "dependencies": { "@lit/context": "^1.1.6", diff --git a/package.json b/package.json index 8dd6b9e..b3b99f9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "simulink-data-explorer", "displayName": "Simulink Data Explorer", "description": "Explore Simulink models, data dictionaries, MAT-files, and projects as interactive tables and relationship trees.", - "version": "1.39.0", + "version": "1.40.0", "publisher": "mathworks", "icon": "media/icon.png", "private": true,