Release Notes 2026-06-20

Release Notes 2026-06-20

Version Information

OpenEdge Release

Version Information

OpenEdge Release

Version Information

11.7.21, 12.2.19, 12.8.9, 12.8.11, 13.0.0

Release 11.7 #89277@2026-06-20

Retirement of OpenEdge 11.7

OpenEdge 11.7 has been retired by Progress Software on April 1st 2025. In consequence we urge all customers still using OpenEdge 11 to upgrade to OpenEdge 12.2 or 12.8 as soon as possible.

We are intending to drop the official support of the SmartComponent Library for OpenEdge 11.7 during the second half of the year 2025. We will then no longer ensure that new features of the framework will be usable with OpenEdge 11.7

Customers that are concerned by this intention, should reach out to us as soon as possible, so that we can discuss about a solution.

OpenEdge 13.0 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 13.0. We hereby declare OpenEdge 13.0 fully supported for the SmartComponent Library as of the release of February 15th 2026.

OpenEdge 12.8 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 12.8. We hereby declare OpenEdge 12.8 fully supported for the SmartComponent Library as of the release of January 15th 2024.

OpenEdge 12.2 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 12.2. We hereby declare OpenEdge 12.2 fully supported for the SmartComponent Library as of the release of April 09th 2020.

PASOE / OEMANAGER VS Code Extension

Our first VS Code extension is available in the VS Code marketplace: https://marketplace.visualstudio.com/items?itemName=ConsultingwerkApplicationModernizationSolutionsLtd.oemanager

The extension supports developers with PASOE related routine tasks during development:

  • checking agent or session status

  • trimming the PASOE agents

  • restarting a new agent vai the ping request

Introducing the SmartComponent Library developer forum

Got questions about using the SmartComponent Library? Wish to discuss feature requests with other users of the SmartComponent Library? To facilitate networking in the growing number of SmartComponent Library users and developers, we've added a developer forum on our new home-page. The developer forum can be found at: https://www.consultingwerk.com/support/forum

A login is required to participate in the forum. Don't be shy - create your account today!

Release Notes

Following the release of the OpenEdge 11.7 Release we have completed our testing of the SmartComponent Library on this release of Progress and are proud to announce formal support for the SmartComponent Library on OpenEdge 11.7 with the 2017-04-24 release of the SmartComponent Library. Generally we recommend customers on OpenEdge 11 to upgrade to OpenEdge 11.7 quickly. Starting the 2017-07-14 release we are supporting OpenEdge 11.7 Service Pack 1 (11.7.1).

Starting the 2015-10-09 release the Business Entity Designer will feature a start page with links to most recent release note articles on this site.

With SCL-751 we have adopted native Enums for OpenEdge 11.6. To activate this feature customers must add a definition to products.i. SCL-751 provides details for this.

With SCL-1113 we have modified the templates for SmartWindowForms and SmartTabFolderPages generated from the Business Entity Designer. We have removed the initialization of the viewer controls SmartTableIOState property (value was set to "NoDataSource" within the InitializeComponent method). Customers using their own set of templates should adopt the same fix to their templates.

New Versions of Proparse .NET Assemblies (30 December 2018)

We have updated proparse with further enhancements in this release (see https://github.com/consultingwerk/proparse/releases/tag/4.0.1.1177). Please download the .NET Assemblies ZIP file from our ESD and replace the proparse.net.dll in your environment with the latest one. The new assembly reference is:

<assembly name="proparse.net, Version=4.0.1.1177, Culture=neutral, PublicKeyToken=cda1b098b1034b24"/>

<assembly name="proparse.net, Version=4.0.1.1177, Culture=neutral, PublicKeyToken=cda1b098b1034b24"/>

As proparse is used by our Business Entity Generator, this new version of the proparse.net Assembly is also relevant for customers not doing GUI for .NET development and require support for parsing new ABL language constructs.

This version of proparse provides additional debug information when errors are thrown from proparse.net.dll.

New Version of the Consultingwerk.SmartComponents Assemly (09 January 2019)

To support the new SmartFilterControl and the "Filter" link between the SmartFilterControl/SmartDynamciFilterControl and a SmartBusinessEntityAdapter or SmartDatasetChildAdapter we have updated the Consultingwerk.SmartComponents.dll. The new Assembly reference is:

<assembly name="Consultingwerk.SmartComponents, Version=2.2.0.49856, Culture=neutral, PublicKeyToken=10603cb31df311b3"/>

Customers need to update this Assembly in order to compile the latest releases of the SmartComponent Library.

Hybrid Realm now using IAuthenticationService

We've updated the SmartHybridRealm class used for http authentication to leverage the IAuthenticationService. It is therefor required that for AppServers requiring http Authentication (e.g. REST or Web) the correct IAuthenticationService implementation is registered (using service.xml files).

Customers relying on the previous behavior should ensure that the Consultingwerk.SmartFramework.Authentication.AuthenticationService is regsitered as the IAuthenticationService. This implementation will auhtenticate users against the password stored in the SmartUser database table.

When users with no Login Company set should be able to login using the SmartHybridRealm, it's required to set the Login Company Tennant Domain (similar to the field in the Login Company Maintenance) in the .restapplicationsettings / .applicationsettings, e.g.:

"DefaultAuthenticationDomain": "consultingwerk"

"DefaultAuthenticationDomain": "consultingwerk"

This is required as the Hydrid Realm Interface from Progress does not provide the domain name to the authentication method.

Web Handler overview

This is an overview of the web handlers supported by this release

defaultHandler=OpenEdge.Web.CompatibilityHandler handler1=Consultingwerk.OERA.JsdoGenericService.WebHandler.CatalogWebHandler: /Catalog/{EntityName} handler2=Consultingwerk.OERA.JsdoGenericService.WebHandler.CatalogsWebHandler: /Catalogs/{PackageName} handler3=Consultingwerk.OERA.JsdoGenericService.WebHandler.CountWebHandler: /Resource/{EntityName}/count handler4=Consultingwerk.OERA.JsdoGenericService.WebHandler.ResourceSubmitWebHandler: /Resource/{EntityName}/SubmitData handler5=Consultingwerk.OERA.JsdoGenericService.WebHandler.InvokeMethodWebHandler: /Resource/{EntityName}/{MethodName} handler6=Consultingwerk.OERA.JsdoGenericService.WebHandler.ResourceWebHandler: /Resource/{EntityName} handler7=Consultingwerk.OERA.JsdoGenericService.WebHandler.BusinessServicesWebHandler: /BusinessServices/{OutputFormat}/{PackageName} handler8=Consultingwerk.Web2.WebHandler.SmartMenuWebHandler: /SmartMenu/{MenuStructureId} handler9=Consultingwerk.Web2.WebHandler.SmartMenuStructureWebHandler: /SmartMenuStructure handler10=Consultingwerk.Web2.WebHandler.SmartRoutesWebHandler: /SmartRoutes handler11=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{EntityName}/{ViewName}/{DetailTemplate} handler12=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{EntityName}/{ViewName} handler13=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{CustomViewName} handler14=Consultingwerk.Web2.Services.SmartViewsHandler.SmartViewerWebHandler: /SmartViewer/Viewer/{EntityName}/{ViewName} handler15=Consultingwerk.Web2.Services.SmartViewsHandler.SmartViewerWebHandler: /SmartViewer/Viewer/{ObjectName} handler16=Consultingwerk.Web2.Services.SmartViewsHandler.SmartFormWebHandler: /SmartForm/{FormTemplate}/{EntityName}/{ViewName} handler17=Consultingwerk.Web2.Services.SmartViewsHandler.SmartFormWebHandler: /SmartForm/{FormTemplate}/{ObjectName} handler18=Consultingwerk.Web2.WebHandler.SmartMessageWebHandler: /SmartMessage/{MessageGroup}/{MessageNumber} handler19=Consultingwerk.Web2.WebHandler.GetImageWebHandler: /Image/{FileName} handler20=Consultingwerk.Web2.WebHandler.SmartValueListWebHandler: /ValueList/{ValueList} handler21=Consultingwerk.Web2.WebHandler.SmartAttachmentsWebHandler: /Attachments/{Table}/{KeyValues} handler22=Consultingwerk.Web2.WebHandler.SmartAttachmentWebHandler: /Attachment/{Guid} handler23=Consultingwerk.Web2.WebHandler.SessionContextWebHandler: /SessionContext handler24=Consultingwerk.Web2.WebHandler.ContextPropertiesWebHandler: /ContextProperties/{PropertyName} handler25=Consultingwerk.Web2.WebHandler.ContextPropertiesWebHandler: /ContextProperties handler26=Consultingwerk.Web2.WebHandler.SessionInfoWebHandler: /SessionInfo handler27=Consultingwerk.Web2.WebHandler.FileSearchWebHandler: /FileSearch/{FileName} handler28=Consultingwerk.Web2.WebHandler.ExecuteAblWebHandler: /ExecuteAbl handler29=Consultingwerk.Web2.WebHandler.SmartLanguagesWebHandler: /Languages handler30=Consultingwerk.OERA.RestResource.RestEntitiesWebHandler: /Entities handler31=Consultingwerk.OERA.Swagger.SwaggerWebHandler: /Swagger/{EntityName} handler32=Consultingwerk.OERA.Swagger.SwaggerRestEntitiesWebHandler: /SwaggerEntities/{OutputType} handler33=Consultingwerk.Web2.WebHandler.SmartTokenSecurityCheckWebHandler: /TokenSecurityCheck/{ObjectName} handler34=Consultingwerk.Web2.WebHandler.SmartTokenSecurityCheckWebHandler: /TokenSecurityCheck handler35=Consultingwerk.Web2.WebHandler.SmartEntityTableMappingHandler: /EntityTableMapping/{EntityName}/{TableName}/{UiTypeCodes} handler36=Consultingwerk.Web2.WebHandler.SmartTreeRootNodeWebHandler: /SmartViews/TreeRootNode/{rootnodeid} handler37=Consultingwerk.Web2.WebHandler.SmartTreeChildNodesWebHandler: /SmartViews/TreeChildNodes/{parentnodeid} handler38=Consultingwerk.Web2.WebHandler.SmartSecurityCheckWebHandler: /IsRestricted/{SecurityRealmCode}/{SecurityItemGuid} handler39=Consultingwerk.Web2.WebHandler.SmartFieldSecurityCheckWebHandler: /RestrictedFields/{TableName} handler40=Consultingwerk.Web2.WebHandler.GetImageNamesHandler: /ImageNames handler41=Consultingwerk.Web2.WebHandler.ExecuteQueryWebHandler: /ExecuteQuery handler42=Consultingwerk.Web2.WebHandler.TranslationProviderWebHandler: /GetTranslation

UTF-8 based deployments available

Starting August 14th 2016 we ship our source code also as UTF-8 encoded. The ZIP files ending with _utf8.zip contain the source code encoded with that code page. The source code in the remaining archives is still encoded in ISO8859-1. Also on Github there is a new branch containing the OpenEdge 11 based source code in UTF-8.

Related article (Progress K-Base): How to get Progress Developer Studio to save in UTF-8 encoding

New Feature Documentation

Download Link

http://esd.consultingwerkcloud.com/

https://github.com/consultingwerk/SmartComponentLibrary

Overview of included tickets

New FormLruController component adds Last-Recently-Used record support to forms

A new component, Consultingwerk.Windows.Controls.FormLruController, provides Last-Recently-Used (LRU) record tracking on forms. It wraps the existing UltraRibbonLruController and wires a form together with a SmartBusinessEntityAdapter, so a single constructor call enables a working LRU list in the Ribbon application menu. Developers call StoreLruEntry to remember the current record (from OnShown or the adapter's AfterUpdateRecord event), and selecting an entry re-selects the record via FindRowWhere.

UserTableStats service now supports LOB Statistics

The UserTableStats service has been extended to support LOB activity statistics, using the LOB investigation capability introduced in OpenEdge 12.0. Developers can now retrieve LOB statistics through the UserTableStats service.

EnableRules and VisibilityRules now supported for fields, buttons, and group boxes in viewers

Fields, buttons, and group boxes within a viewer can now be enabled or made visible dynamically based on logical EnableRules and VisibilityRules expressions. The expressions are parsed with the TokenResolver class and evaluated into a logical result via the AblExpressionEvaluator, with tokens resolving against viewer fields, viewer properties such as SmartTableIOState, or the underlying data-source adapter. Developers set the EnableRules and VisibilityRules repository attributes on the controls of a SmartViewerControl-derived component; the rules are evaluated during rendering and re-evaluated reactively as the user navigates records or edits field values.

EnableRules support added for custom toolbar buttons in the Windows (GUI for .NET) client

Toolbar buttons in the Windows (GUI for .NET) client now support EnableRules that conditionally enable or disable buttons based on field values, data-source state, and SmartTableIOState. Rules are defined in the button JSON files and resolved reactively via the TokenResolver and AblExpressionEvaluator classes, so buttons re-evaluate automatically as the user navigates grid records or edits viewer fields. Developers reference fields and properties directly, or through form-instance qualified tokens such as ${OrderCustomerDataSource.SmartDataSourceState}, optionally combined with logical operators.

Fixed: Saving multiple changes in the Repository Viewer Designer no longer raises a record-changed error

Fixed a bug in the Repository Viewer Designer where saving several changes at once (for example removing a label control while changing the LABEL and NoLabels properties of another field) raised a "current row has been changed by another user" error on the eSmartAttributeValue table. Changes are now saved correctly in a single operation. No changes required in customer code.

IKVM and Proparse upgraded for current .NET tooling

The IKVM toolchain used to build and run Proparse.Net.dll was upgraded, and an alternative .NET Core build of Proparse was investigated so both variants remain available. This keeps the Proparse-based ABL parsing tooling current with modern .NET runtimes. No changes required in customer code.

Tab folder record counts are now retrieved asynchronously when connected to an AppServer

Tab folder record counts are now performed asynchronously when connected to an AppServer, following the existing RetrieveDataAsync pattern. This prevents the user interface from blocking while count requests run on the server. No changes are required in customer code to benefit from the asynchronous counting.

DB Table Maintenance now supports Mandatory and Add-Only columns

The SmartFramework DB Table Maintenance now includes Mandatory and Add-Only column attributes. When importing database tables, mandatory fields are automatically populated based on the database schema, and the SmartDataAccess layer now validates these attributes during Add and Update operations. Developers benefit from consistent enforcement of mandatory and add-only fields directly from the data access layer.

Improved: PASOE Session Telemetry NDJSON output now emits properties in a logical, grouped order

The PASOE Session Telemetry NDJSON output previously emitted properties in an order that did not match the intended grouping. Properties are now written in a defined order so that logically related fields (top-level sample fields, the metrics object, and the agents and sessions arrays) are grouped together. Consumers parsing the NDJSON by key are unaffected; only the property ordering changed. No changes required in customer code.

RESTful Entities now support CREATE and DELETE redirection between Query and Maintenance Business Entities

When a read-only query Business Entity provides the collection endpoint and a separate maintenance Business Entity provides the record endpoint, create and delete operations on the collection endpoint can now be redirected to the maintenance Business Entity. Developers configure this with the @RestAddress annotation using type 'collection' together with an updateBusinessEntity attribute that names the maintenance Business Entity.

Scheduler now supports interval-based plans (every X seconds, minutes, or hours)

The Scheduler now supports recurring interval plans defined by a time unit (seconds, minutes, or hours) and a time value. Intervals can be calculated relative to either the start or the end time of the previous execution. Developers can configure these plans to run tasks at fixed intervals without defining explicit calendar schedules.

Added: FSWatcher npx task is now supported on Linux

The FSWatch npx task can now run on Linux in addition to Windows. This required switching from the Proparse-based annotation parser to the XREF-based annotation parser (XrefAnnotationParser) and bundling a few additional files for the Linux deployment. Developers can now use the file-system watcher on Linux as part of their build/development workflow.

SmartValueLists now support dynamic value lists sourced from a Business Entity or service method

SmartValueLists can now be populated dynamically at runtime from a Business Entity or a service method instead of statically maintained entries, configured through new fields in ValueList Maintenance such as EntityName, EntityTable, KeyField, DescriptionFields, or a Service Type name and Service method. The two source options are mutually exclusive and validated bidirectionally in Consultingwerk.SmartFramework.System.ValueListBusinessEntity, ensuring a value list is either statically maintained or dynamically sourced but never both. Dynamic retrieval is implemented in Consultingwerk.Windows.Framework.System.ValueListProvider and Consultingwerk.Web2.WebHandler.SmartValueListWebHandler, with optional caching of Business Entity datasets. The same mechanism also feeds badge rendering based on Business Entity data through the BadgeProvider.

SmartDbManager graceful shutdown now waits for running scripts to finish

The graceful shutdown of the SmartDbManager has been optimized to wait for any child processes (scripts) to finish before the process exits. Previously, running scripts were interrupted abruptly during shutdown. No changes required in customer code.

SmartDB Manager can now download the log file of the current script run

The SmartDB Manager now supports downloading the log file of the current or last-completed script run (init-branch, import-repository-data, export-repository-data), similar to downloading a Jenkins log file. Developers and operators can retrieve the full log of a script execution directly from the SmartDB Manager interface.

Business Entity Designer now enforces XML-compatible serialize names when adding tables and fields

The Business Entity Designer (both desktop and web/MCP) now automatically generates an XML-compatible SERIALIZE-NAME whenever a table or field name contains a character that is valid in an ABL database field name but not in an XML schema element name (such as '#'). It is implemented as a Business Entity Designer plugin sharing an abstract base class across desktop and server. Invalid characters are replaced with an underscore; the replacement character is exposed as a STATIC PUBLIC property of the abstract base class (default '_') so it can be changed through configuration.

Added an 'Update SmartDB Schema' button to the SmartDB Manager UI

A new 'Update SmartDB Schema' button was added to the SmartDB Manager user interface, which runs the Scripts/update-smartdb-schema.cmd script. Developers can now trigger a SmartDB schema update directly from the manager UI instead of running the script manually.

Added repository property sheets for Lookups, MetaDataSource, and Combo-Boxes

Custom repository property sheets were implemented in the Consultingwerk.Windows.Framework.Repository.PropertySheets namespace, replacing the earlier sample implementations. The new sheets include MetaBusinessEntityLookupPropertySheet for lookups, MetaDataSourcePropertySheet (with entity name, table, view, batch size and a query editor with code completion), and MetaBusinessEntityComboBoxPropertySheet for combo-boxes. Developers now get a more polished, well-grouped editing experience that reads and writes the attribute temp-table.

Repository Forms Overview now provides ribbon buttons to create desktop and web menu items for the selected form

Two new buttons, "Create Desktop Menu Item" and "Create Web Menu Item", were added to the ribbon of the Repository Forms Overview. They route to new server-side event handler methods (CreateDesktopMenuItemToolClick and CreateWebMenuItemToolClick) on MetaFormRepositoryObjectsFormLogic, which prompt the developer for menu item details (name, module, images, and for web the function code, view URI and title) pre-populated from the selected form. On confirmation a SmartFunction record is created with a serialized LaunchFormCallParameter (desktop) or LaunchWebViewCallParameter (web) instance. Developers can use these buttons to quickly generate desktop or web menu items that launch the currently selected form.

Alphabetical sorting added to the Reorder Menu Items dialog

A new toolbar button has been added to the Reorder group of the Reorder Menu Items dialog, allowing menu items to be sorted alphabetically with a single click. The sort is applied to the in-memory list and is only persisted when the user confirms with Ok, while Cancel still discards the change. The new sorting option is available automatically in the dialog; no changes are required in customer code.

Frame migration: LayoutStyle (Responsive vs Pixel) of generated Repository MetaViewer is now configurable

The Legacy GUI Frame migration tool now lets the user control the LayoutStyle property (Responsive or Pixel) of the generated MetaViewer. A new LayoutStyle field with initial value Responsive was added to the ttAblFrameMigrationSettings temp-table in Consultingwerk.Studio.LegacyGuiMigration.Frame.AblFrameMigrationSettings and is persisted to the settings file, with an UltraComboEditor added to the settings dialog offering the values Responsive and Pixel. The chosen value is applied to the LayoutStyle property of the generated MetaViewers.

Frame migration: VerticalStretch attribute of generated Repository MetaViewer is now configurable

A new setting in the Legacy GUI Frame migration tool controls the VerticalStretch attribute of the generated Repository MetaViewer. The setting was added as a logical field on the ttAblFrameMigrationSettings temp-table and is editable via the settings form, so it travels with the rest of the Frame migration settings.

Browse Repository Objects forms now include a filterable and sortable Product Name column

The Browse Repository Objects forms now include an additional Product Name grid column for each repository object. The column is filterable via the grid filter row and stored filters, and sortable via the column header, consistent with the existing columns. This applies across all Browse Repository Objects forms for the different object types.

Frame migration: border-all style for rectangles on generated Repository MetaViewer is now configurable

When migrating a legacy GUI Frame into a Repository MetaViewer, a new setting controls whether rectangles in the generated MetaViewer receive the border-all style. The setting was added as a logical field on the ttAblFrameMigrationSettings temp-table and is editable via the settings form, so it is persisted together with the other Frame migration settings.

ActionType implemented as server-side Business Entity Designer plugin

ActionType has been implemented as a server-side Business Entity Designer plugin so it can also be used in the MCP server. The implementation was verified against Consultingwerk.SmartFramework.Repository.Object.ObjectMasterBusinessEntity.

New class Consultingwerk.Util.DateHelper provides Gregorian Easter Sunday calculation

A new class Consultingwerk.Util.DateHelper has been added with a static method EasterSunday(piYear AS INTEGER) that returns the date of Easter Sunday for a given year, calculated according to the Gregorian calendar algorithm. The method validates its input and throws a meaningful exception for years before the introduction of the Gregorian calendar (before 1583) or outside the supported OpenEdge DATE range. Unit tests cover the documented reference years and the earliest (22 March) and latest (25 April) boundary dates.

Active Table IO Target name is now passed with Toolbar/Ribbon server-side event handler invocations

A new TableIoTargetName property has been added to Consultingwerk.CommonUi.EventHandlerParameter and IToolClickEventHandlerParameter. The event dispatcher service and the frontend (SmartComponent Library in GUI for .NET and SCLNG) now send the name of the active Table IO target with each server-side event handler invocation. Developers can read TableIoTargetName from the event handler parameter in their server-side handlers to identify which Table IO target was active.

Toolbar/Ribbon ToolClick events now consistently send the dataSource's current record to the backend

The Toolbar/Ribbon ToolClick server-side event handler now consistently transports the current record of the configured dataSource to the backend, regardless of the dataSource component type. Viewer and grid behavior is unchanged, while the SmartBusinessEntityAdapter and the SmartDatasetAdapter / SmartDatasetChildAdapter cases now correctly assemble and send a dataset containing the current row. Developers can rely on the current record being available in the Business Task invoked from a toolbar or ribbon button that defines a dataSource.

Uppercase ABL keywords in the Consultingwerk.OERA package converted to lowercase

All uppercase ABL keywords across the 379 files of the Consultingwerk.OERA package were converted to lowercase to align with the current ABL coding rules and the @lowercase convention. Type names, property names, method names, preprocessor names, temp-table names, enum members and string literals were preserved. No changes required in customer code.

AppBuilder and Data Dictionary shortcuts added to the SmartComponent Library Desktop 2

The SmartComponent Library Desktop 2 now provides shortcuts to launch the AppBuilder (in the Development group) and the Data Dictionary (in the Management group) using the current project configuration, each with a dedicated icon. No changes required in customer code.

Fixed: Nested can-find (… where …) predicates no longer break parenthesis balance in merged query strings

When a client filter is AND-merged into a buffer's existing where clause, QueryString:InsertExpression now wraps only the buffer's main where clause in parentheses instead of every where token. Nested where keywords inside can-find (…) sub-expressions are left untouched, so the generated prepare-string stays balanced and prepares correctly. This resolves the AVM parser errors 247, 253 and 7324. No changes required in customer code.

Renamed openedge-version.cmd to scl-workspace-config.cmd to better reflect its purpose

The workspace configuration script openedge-version.cmd was renamed to scl-workspace-config.cmd, since over time it has grown to configure more than just the OpenEdge release. All other scripts in the repository that invoked openedge-version.cmd were updated to call the new name. Developers with custom scripts or environment setups that reference the old openedge-version.cmd name must update those references accordingly.

New KeywordCaseProcessor tool corrects ABL keyword case in source files

A new tool, Consultingwerk.Studio.SourceCode.KeywordCaseProcessor, corrects the case of ABL keywords in .p, .w, and .cls source files. The CorrectKeywordCase method parses the program through IProparseApi, walks the abstract syntax tree, and enforces lowercase or uppercase on keyword nodes, optionally inserting the @lowercase. or @uppercase. annotation when missing. The IProparseApi service was extended with a new IsKeywordType method to support this processing. Developers can use this tool to standardize keyword casing across their source code.

Added: ProparseWebApi now implements IsKeywordType(NodeTypesEnum)

The ProparseWebApi implementation of IProparseApi previously threw a "not supported" error for IsKeywordType(NodeTypesEnum). It now provides a full implementation, so the keyword-type check works over the Web API as well, supporting the KeywordCaseProcessor work. Developers can call IProparseApi:IsKeywordType and receive correct results regardless of whether the underlying implementation is ProparseDotNetApi or ProparseWebApi.

Business Entity Designer plugin now corrects keyword case in generated source code

A new Business Entity Designer plugin automatically corrects the keyword case of generated source code, driven by the BusinessEntityDesignerSettings:KeywordCasing setting. It hooks into the AfterWriteFile event of the BusinessEntityGenerator and applies the configured casing using the KeywordCaseProcessor. The plugin is implemented as both a frontend and a server plugin sharing an abstract base class.

SmartDB Manager now displays the base database path (branches folder) below the database list

The SmartDB Manager now shows the base database path (the branches folder) beneath the list of databases, rendered slightly dimmed for visual de-emphasis. This gives developers immediate context about which branches folder the displayed databases belong to. No changes required in customer code.

Lookup support added to server-side event handler InputPrompts

Server-side event handler InputPrompts now support type=lookup fields through the new InputPromptLookupPropertyOptions class, complementing the existing InputPromptComboBoxPropertyOptions. Developers can control whether the lookup assigns the Text/Value (KeyField) or the KeyValue (KeyValueField) to the parameter object property, and can either reference a lookup definition from the repository via SmartBusinessEntityLookupDescriptor:FromRepository or supply the relevant lookup properties directly within the server-side event handler method implementation. This ticket adds the InputPrompt extension and the frontend support for GUI for .NET; Angular support is tracked separately.

Dialog button order adjusted so the affirmative button precedes the negative button

Confirmation dialogs now place the affirmative ('Yes' style) button before the negative ('No' style) button, following common European user interface conventions. Similar dialogs were reviewed and aligned to the same button order. No changes required in customer code.

New Agent Skill added for modifying the schema of an OpenEdge database

A new Agent Skill in the Studio component supports modifying the schema of an OpenEdge database, including an Ant script that loads a DF file after verifying there are no active database connections, plus supporting documentation explaining the DF file structure and the Consultingwerk schema definition standards. Sample DF files are provided for common operations such as a full table, small incremental changes, renaming tables, indexes and fields, and changing the primary index. In this first version the skill intentionally avoids field drops and data-type changes.

Fixed: File watcher (fswatcher) now runs correctly on Linux and WSL environments

The file watcher (fswatcher) previously assumed a Windows environment and failed to execute the configured Ant commands on Linux and WSL, because it used Windows-style paths and command syntax. The fswatcher now detects the operating system and builds platform-appropriate paths and Ant invocations, so file-change-triggered annotation extraction works correctly on Linux and WSL. No changes are required in customer code.

Fixed: SSL Certificate Importer now parses both 'CN=value' and 'CN = value' openssl subject formats

The SSL Certificate Importer no longer fails when openssl renders the certificate subject in the compact 'CN=value' form, which previously produced an illegal filename starting with a colon and aborted the import. A new ExtractCommonName helper in SslCertificateHelper now accepts both 'CN=value' and 'CN = value' and raises a clear error when no CN is present. No changes required in customer code.

Shared dlc-registry.cmd added for OpenEdge DLC lookup; OpenEdge 13.0 supported and end-of-life versions dropped

A new shared helper script Consultingwerk\Studio\bin\dlc-registry.cmd now centralizes the Windows registry lookup that determines the OpenEdge DLC installation path. All six SmartComponent Library Studio batch scripts (certificate importer, scaffolding generator, static names generator, interface generator, PASOE helper and record-count helper) call this single helper instead of duplicating the lookup block, so the supported OpenEdge version list is maintained in one place. Support for end-of-life OpenEdge releases (11.3 through 11.6, 12.0, 12.1, 12.3 through 12.7) was removed, while 11.7, 12.2 and 12.8 are retained. Support for OpenEdge 13.0 (both 64-bit and 32-bit registry entries) was added at the top of the version probe order.

Document Viewer source-configuration attributes are now rendered into the layout JSON and configurable in the repository designer

DocumentViewerWebRendering now emits the Document Viewer source-configuration attributes (sourceType, baseUrl, urlFieldName, urlSubstitute, fileNameField and backendService) into the Angular layout JSON, and resolves the dataSource value from its repository Data-Link rather than from an attribute. Corresponding repository designer UI was added so these attributes can be configured directly. As a result, developers can now set up the Document Viewer source through the repository designer instead of hand-crafting layout JSON or calling showDocument() from form logic.

DeleteUnsupportedAttribute method added to the Unsupported Attributes Report Business Task to support the report's Delete button

A new DeleteUnsupportedAttribute method has been added to the UnsupportedAttributesReportBusinessTask class. The method accepts a CharacterHolder parameter and is decorated with the @InvokeMethod annotation, mirroring the existing DeleteOrphanRecord method on SmartRepositoryIntegrityCheckTask. This provides the backend logic behind the Delete button on the Unsupported Attributes Report web form, allowing a developer to remove an unsupported attribute directly from the report.

Fixed: Cancelling Add child in Object Type Maintenance no longer throws errors or leaves a phantom treeview item

In the Repository Object Type Maintenance screen, choosing the Add child option and then clicking Cancel Update no longer raises 'No record is available in buffer SmartObjectType.' errors or leaves a phantom treeview item behind. No changes required in customer code.

FormClosing and FormClosed Smart Form attributes are now rendered in JSON layouts

The Smart Form repository attributes FormClosing and FormClosed are now emitted in the JSON layout output, so the front end can read them and wire up the corresponding server-side event handler subscriptions introduced in SCL-4516.

Web2 EventDispatcherService now deserializes SCLNG ModalFormClosed payload fields

The Web2 EventDispatcherService:DeserializeEventHandlerParameter method was extended to understand the additional payload fields sent when SCLNG fires a parent form's ModalFormClosed server-side event, including launchedFormName and launchedFormParameter (in both lower-camel and Pascal case) alongside dialogResult, formResult and formResponse. These fields now populate the corresponding EventHandlerParameter / modal-form-closed parameter state used by backend server-side event handlers.

Added FileHelper:IsFolderWritable methods to check whether a folder is writable

Two new methods were added to the FileHelper class: IsFolderWritable(folderName, throwOnNotWritable) and an overload IsFolderWritable(folderName) that calls it with FALSE. Relative folder names are resolved via FileHelper:FindFile, and a non-existent folder raises a meaningful exception. The method attempts to create a uniquely named test file in the folder, returns TRUE on success, and either returns FALSE or throws a meaningful error depending on the flag if the file cannot be created; the test file is always removed afterwards. Developers can use this to return a useful error when, for example, an AppServer user lacks write permission to a folder used for saving generated PDFs.

scl-gen-interface CLI tool now handles classes containing static dataset or temp-table definitions

The scl-gen-interface tool previously copied static dataset and temp-table definitions from class-level include files into the generated interface, causing compile errors because static temp-table definitions are not allowed in interface definitions. The tool now excludes these static definitions, so interfaces generated for such classes compile cleanly. No changes required in customer code.

SmartComponent Library Ant appserver filesets now include images to support SFRBO

The Ant appserver build fileset (smartcomponents.delete.appserver.nodemo in smartcomponents.xml) previously excluded image files. To support the SFRBO implementation, which requires certain images on the backend, the appserver fileset now includes these images in the build.

Refresh from Database now removes fields that no longer exist in the database from DeletedFields

When using the 'Refresh from Database' tool in the Business Entity Designer, fields listed in eTable.DeletedFields of the dsBusinessEntity dataset are now checked against the database. A field that no longer exists in the database is removed from the DeletedFields entry, while fields that still exist in the database but are not part of the temp-table remain. This prevents obsolete field names from appearing in code-base searches.

Added Consultingwerk.Assertion.Assert:IsNull and IsNullOrZero assertion methods

The Consultingwerk.Assertion.Assert class has been extended with IsNull and IsNullOrZero methods that mirror the existing NotNull and NotNullOrZero methods with inverted semantics. The same set of data-type overloads is provided, so developers can assert that a value is null or null/zero. Unit tests covering both the passing and failing cases were added for every new overload.

Added: the SettingsKey attribute is now rendered into the Smart Grid layout for Web and Windows

The SettingsKey grid attribute is now rendered into the grid's componentOptions JSON by GridWebRendering and into the Windows layout by GridRenderer. When set, the Web Client uses it as the storage key for grid preferences (such as remembered filters), so a single grid object reused across data sets can keep separate stored filters. The settingsKey property is only emitted when the attribute has a non-empty value and is guarded with BufferHelper:HasField, so existing grids and older repositories are unchanged. The attribute itself must be added to the repository by the developer.

Improved: SmartMDIContainer skips redundant MDI title-bar repaints when the title is unchanged

SmartMDIContainer:UpdateTitleWithMdiChild assigned the form Text on every current-row change, and because a WinForms Text setter forces a title-bar repaint even for an identical value, this caused a redundant repaint on every data refresh. The new title is now computed into a local variable first, and the assignment (and the associated TextChanged unsubscribe/subscribe churn) is skipped when it already matches the current title, using a case-sensitive comparison. Behaviour is unchanged when the title genuinely changes. No changes required in customer code.

Improved: SmartDataBrowser memoizes the schema-stable large-column scan across data retrieves

SmartDataBrowser:FormatColumns runs on every data retrieve (every filter, sort, refresh and page) and previously re-scanned the binding-source schema for BLOB/CLOB columns each time. The large-column lists (BindingSourceLargeColumns and QueryLargeColumns) are now memoized on the SmartDataBrowser instance, keyed by the binding-source object identity, and reused while the binding source is unchanged. The cache is self-invalidating because re-binding the grid produces a different binding-source reference, and the computed result is identical to before. No changes required in customer code.

Fixed: ProfilerForm Debug Listing folder picker now returns the selection and validates folder/output paths

In the ProfilerForm, the Debug Listing folder picker did not return the selected folder, and folder and output-file paths were not validated. The picker now returns the chosen folder, the selected folder and the output-file directory are validated for existence and writability, and the Start button is disabled when validation fails. No changes required in customer code.

Improved: window-position restore no longer uses per-form .NET reflection on every form open

BaseFormHelper:RestoreWindowPosition parsed the window state on every form open using two relatively expensive reflection calls (TypeHelper:GetType and System.Enum:Parse). The FormWindowState type is now cached once and the window-state string mapped directly without reflection. This reduces form-open time while window position, size and the maximized/minimized state are restored unchanged. No changes required in customer code.

Improved: the Runtime Repository Developer Menu is no longer rebuilt on every dynamic form open

The Runtime Repository Developer Menu (RuntimeRepositoryDeveloperMenuRenderer) previously reconstructed all of its tools, appearances and images from scratch on every dynamic form open for authorized developer sessions. The menu tool definition is now built once and reused on subsequent forms, and the token-security lookup result is cached for the session. This noticeably reduces dynamic form open time while keeping the Developer Menu fully functional. No changes required in customer code.

Improved: SmartDataBrowser column formatting no longer repeats .NET reflection and large-column scans per grid layout

SmartDataBrowser:FormatColumns previously resolved the System.Int32 and System.Decimal types via reflection (TypeHelper:GetType) and recomputed the large-column lists on every grid layout pass. The .NET type references are now cached in static fields and the large-column results (BindingSourceLargeColumns / QueryLargeColumns) are memoized while the schema is unchanged. Grid formatting (numeric column formats, sort indicators and large-column handling) is identical. No changes required in customer code.

Improved: the Quick Access Toolbar is no longer fully cleared and rebuilt on every form open

UltraToolbarsHelper:RestoreQuickAccessToolbarTools previously cleared the Quick Access Toolbar and re-added every tool one-by-one on each form open. It now compares the desired tool list against the tools already present and applies only the delta within a batched, layout-suspended update. This reduces form-open overhead while the Quick Access Toolbar is restored identically (same tools, order and popup-group tools). No changes required in customer code.

Improved: reduced logging-guard and service-lookup overhead on the form-open and render path

On the form-open and render path, hot-path callers used to build log message strings and invoke LogManager:WriteMessage unconditionally, and resolve session-singleton services (ServiceContainer:GetService / FindService) thousands of times per form open even when logging was off. A cheap cached "is logging active" guard now lets callers skip message construction, IsCustomLogEntryTypeActive results are cached per entry type, and frequently used service references are cached on the consuming components. Logging output and service-resolution behaviour are unchanged. No changes required in customer code.

Improved runtime layout performance by consolidating geometry changes into SetBounds calls

Runtime sites that set two or more of Top/Left/Width/Height together on .NET Forms and Controls (outside the Visual Designer's InitializeComponent) were consolidated into single Control:SetBounds calls, applying location and size in one layout pass instead of one pass per property. The change targets hot paths such as form open, control rendering and dynamic layout (including BaseFormHelper and the Windows repository rendering renderers), with unchanged visual layout and behaviour. No changes required in customer code.

Improved toolbar build performance by batching Infragistics tool additions into single array-based Tools:Add calls

On the prioritized hot paths (such as the Business Entity Designer toolbar assembly and ribbon/toolbar construction), sequences of single-tool Tools:Add calls were consolidated into a single Tools:Add call that accepts a ToolBase array, so the Infragistics toolbars framework performs its per-add bookkeeping and layout work once instead of repeatedly. The resulting toolbars and ribbons are identical (tool order, keys, shared props and appearances unchanged), and isolated single-tool adds were left as-is. No changes required in customer code.

ProfilerForm is now accessible directly from the Developer menu

A new entry for the ProfilerForm was added to the Developer menu, allowing developers to open the Profiler directly from there instead of launching it by other means. No changes required in customer code.

Added: LaunchWebView menu functions can now be configured to launch as a modal floating web window

The Consultingwerk.Web2.SmartFramework.Menu.LaunchWebViewCallParameter class gained a new logical LaunchAsModalWindow property (default false), and LaunchWebViewCallParameterControl was extended so menu function maintenance can edit the flag. The Smart Menu Structure response now exposes the value to web clients, and the FunctionCallParameter JSON remains backward-compatible so existing menu functions without the flag behave unchanged. Developers can set LaunchAsModalWindow = true on a LaunchWebView menu function to have its target open as a modal floating web window.