Compile Time Changes

class PartMakeSpecialDialog

Constructor change

The PartMakeSpecialDialog constructor has been changed to accept a new parameter label. The new parameter allows for customization of the dialogs label but the label is still defaulted to the title "Make/Change Special".

Old: public constructor(Window parent, PartSpecial original) {}
New: public constructor(Window parent, PartSpecial original, str label=$specialsDialog) {}

Added: extend public PartSpecial generateSpecial() {}

The helper method generateSpecial() has been introduced to streamline the process of creating PartSpecial objects from dialog input.

  • Encapsulates the logic for constructing a PartSpecial from dialog contents.
  • Uses current values from UI fields to populate the new object:
return PartSpecial(partNumTF.text,
                   descrTF.text,
                   priceReplaceRB.currentState > 0,
                   amountDF.value);

Added: extend public PartSpecial generateCustomSpecial(PartSpecial original) {}

The helper method generateCustomSpecial() has been introduced to streamline the process of creating custom PartSpecial objects from dialog input.

  • Currently returns null but provides a clear hook for future overrides.

In 16.5, the QueryDialogDataEnv has changed it's backing data structures, replacing the str->Part parts and int->str rowIDs maps with a single QueryRowData[] queryRows data sequence. Cell highlighting has also been introduced in the QueryDialog.

As a result, the following functions have been removed and added to QueryPartGridBuilderEnv.

Removed: public str rowIdentifier(Object data) {}
Added: public GridCell[] getRowCells(Object data) {}
Added: public Brush getCellBrush(Object data, int columnIdx) {}

class QueryDialogDataEnv

In 16.5, The QueryDialogDataEnv has changed it's backing data structures, replacing the str->Part parts and int->str rowIDs maps with a single QueryRowData[] queryRows data sequence.

Old vs. New Behavior

Old:

  • Relied on maps for matching grid row ids to Part instances
    • str->Part parts
    • int->str rowIDs
  • Challenges:
    • Heavily relied on keys and ID management for aligning UI with data
    • Prone to issues with duplicated keys/IDs which led to more complex handling
    • Introduction of custom specials unraveled this structure

New:

  • New atomic data structure to represent single rows in the grid (QueryRowData)
  • New single sequence in data env to hold rows (QueryRowData[] queryRows)
  • Improvements:
    • Direct access to row data using int indexes rather than str keys/ids
    • Single data structure to connect UI and data values
    • Ordered data sequence directly represents grid rows

As a result of this change, the following functions and fields were modified in the QueryDialogDataEnv interface.

// Modified data fields
Old: public str->Part parts;
Old: public int->str rowIDs;
New: public QueryRowData[] queryRows;

// Modified data field accessors/manipulation
Old: extend public Part[] setParts(Part[] value) {}
Old: extend public int->str setRowIDs(int->str value) {}
Old: extend public void buildParts() {}
New: extend public void buildQueryRowData(Part[] parts=null) {}

// Modified to new data structure (str id -> int row)
Old: extend public PartSpecial getSpecial(str id) {} 
New: extend public PartSpecial getSpecial(int row) {}

Old: extend public void putSpecial(str id, PartSpecial special) {}
New: extend public void putSpecial(int row, PartSpecial special) {}

Old: extend public void removeSpecial(str id) {}
New: extend public void removeSpecial(int row) {}

// Added helper functions
New: extend public void refreshQueryRowData() {}
New: extend public QueryRowData createPartRowData(Part part) {}
New: extend public bool contains(PropObj propObj) {}
New: extend public bool any() {}
New: extend public bool empty() {}
New: extend public QueryRowData getRowData(int row) {}

NOTE: Things labelled as Old were removed interface and those labeled as New were added. The Old/New labels are utilized to clearly demonstrate the migration of changes.

In 16.5, the QueryDialogDataEnv has changed it's backing data structures, replacing the str->Part parts and int->str rowIDs maps with a single QueryRowData[] queryRows data sequence.

As a result, the extended type QueryPartRowData has been created to represent a core Part query dialog row.

/**
 * QueryPartRowData
 * 
 * This class is responsible for managing 
 * data for a Part row in a QueryDialog.
 */
public class QueryPartRowData extends QueryRowData {
    
    /**
     * Get the Part instance associated with this row.
     * @return The Part object associated with this row
     */
    extend public Part part() { ... }
    
    
    /**
     * Get the special associated with this row.
     * @return The PartSpecial object associated with this row
     */
    public PartSpecial getSpecial() { ... }
    
    
    /**
     * Assign a special to this row.
     * @special The PartSpecial object to associate with this row
     */
    public void putSpecial(PartSpecial special) { ... }
    
    
    /**
     * Remove the special from this row.
     */
    public void removeSpecial() { ... }
}

class QueryDialogBehavior

Data Backend Changes

In 16.5, The QueryDialogDataEnv has changed it's backing data structures, replacing the str->Part parts and int->str rowIDs maps with a single QueryRowData[] queryRows data sequence. View more documentation about this change in the section for cm.core.part.query.QueryDialogDataEnv.

The following functions in the QueryDialogBehavior have been updated to reflect the new index-based data retrieval versus the old key/id based retrieval. They perform the same purposes with the only notable change being in buildGridWindow which is documented further below.

Old: extend public int->str buildGridWindow(GridWindow grid, Part[] parts) {}
New: extend public void buildGridWindow(GridWindow grid, Object rows) {}

Old: extend public PartSpecial getSpecial(QueryDialog dialog, str id) {}
New: extend public PartSpecial getSpecial(QueryDialog dialog, int row) {}

Old: extend public void putSpecial(QueryDialog dialog, str id, PartSpecial special) {}
New: extend public void putSpecial(QueryDialog dialog, int row, PartSpecial special) {}

Old: extend public void removeSpecial(QueryDialog dialog, str id) {}
New: extend public void removeSpecial(QueryDialog dialog, int row) {}

Old: extend public GridCell[] getRowCells(QueryDialog dialog, str id) {}
New: extend public GridCell[] getRowCells(QueryDialog dialog, int row) {}

Old: extend public GridCell getCell(QueryDialog dialog, str columnLabel, str rowID) {}
New: extend public GridCell getCell(QueryDialog dialog, str columnLabel, int row) {}

Old: extend public DialogWindow getSpecialDialog(QueryDialog dialog, str id) {}
New: extend public DialogWindow getSpecialDialog(QueryDialog dialog, int row) {}
Changed: extend public int->str buildGridWindow(GridWindow grid, Part[] parts) {}

The buildGridWindow function no longer takes in a Part sequence as a parameter and no longer returns an int->str row-index to row-id map. It now accepts a generic Object type for its row building. It's return type has changed to void with the reverted need for row IDs.

Old vs. New Behavior

Old:

  • Accepted Part[] parts as a parameter
  • Built rows directly from Parts sequence
  • Returned int->str map of row-indexes to row-ids for caching on QueryDialogDataEnv

New:

  • Accepts an Object type for a row data parameter
  • Builds rows using GridBuilders generic populateGridWindow function which takes in an Object
  • Returns nothing anymore as row-ids are no longer cached on QueryDialogDataEnv
Impact
  • Developers wanting to manage their grid building should override GridBuilder and it's populateGridWindow interface
    • Supply the customized builder to the QueryDialogBehavior on your PropObj

Other QueryDialogBehavior Changes

The following functions have been modified, added to, or removed from QueryDialogBehavior in v16.5.

Added: extend public QueryRowData[] getQueryRows(QueryDialog dialog) {}
Added: extend public QueryRowData getRowData(QueryDialog dialog, int row) {}
Added: extend public Part getPart(QueryDialog dialog, int row) {}
Added: extend public void openCustomSpecialDialog(QueryDialog dialog) {}
Added: extend public DialogWindow getCustomSpecialDialog(QueryDialog dialog, int row) {}

Removed: extend public bool containsSpecial(QueryDialog dialog) {}
Removed: extend public int getRowIndex(QueryDialog dialog, str id) {}

Added: extend public QueryRowData[] getQueryRows(QueryDialog dialog) {}

  • Returns all QueryRowDatas in the dialogs QueryDialogDataEnv

Added: extend public QueryRowData getRowData(QueryDialog dialog, int row) {}

  • Returns the QueryRowData representing the row at the int row index

Added: extend public Part getPart(QueryDialog dialog, int row) {}

  • Returns the Part representing the row at the int row index

Added: extend public void openCustomSpecialDialog(QueryDialog dialog) {}

  • Opens a dialog (PartMakeSpecialDialog) for generating a custom special representing the row at the selected row index

Added: extend public DialogWindow getCustomSpecialDialog(QueryDialog dialog, int row) {}

  • Gets the dialog (PartMakeSpecialDialog) for generating a custom special representing the row at the selected row index

Removed: extend public bool containsSpecial(QueryDialog dialog) {}

  • This function was removed with the removal of the old data structure in QueryDialogDataEnv
  • See documentation in the above "New Data Backend" section and/or the compile-time section for cm.core.part.query.QueryDialogDataEnv for more info.

Removed: extend public int getRowIndex(QueryDialog dialog, str id) {}

  • This function was removed with the removal of the old data structure in QueryDialogDataEnv
  • See documentation in the above "New Data Backend" section and/or the compile-time section for cm.core.part.query.QueryDialogDataEnv for more info.

class QueryRowData

In 16.5, the QueryDialogDataEnv has changed it's backing data structures, replacing the str->Part parts and int->str rowIDs maps with a single QueryRowData[] queryRows data sequence. As a result, the abstract class QueryRowData has been created to represent a generic query dialog row.

  • Carryies current instance of a row's data (Part, SpecOption, etc)
  • Manipulates specials for the row's data type

Interface

/**
 * QueryRowData
 * 
 * This abstract class is responsible for managing 
 * data for a row in a QueryDialog.
 */
public class QueryRowData : abstract {

    /**
     * ID for this row data instance.
     */
    public str id;
    
    /**
     * The data object associated with this row.
     */
    public Object data : copy=reference;

    
    /**
     * Constructor.
     * @id ID for this row
     * @data The data object to associate with this row
     */
    public constructor(str id, Object data) { ... }


    /**
     * Get the special associated with this row.
     * Override to get specific special handling logic.
     * @return The PartSpecial object associated with this row
     */
    extend public PartSpecial getSpecial() : abstract { }


    /**
     * Assign a special to this row.
     * Override to get specific special handling logic.
     * @special The PartSpecial object to associate with this row
     */
    extend public void putSpecial(PartSpecial special) : abstract { }


    /**
     * Remove the special from this row.
     * Override to get specific special handling logic.
     */
    extend public void removeSpecial() : abstract { }
}

class QueryDialog

Data Backend Changes

In 16.5, The QueryDialogDataEnv has changed it's backing data structures, replacing the str->Part parts and int->str rowIDs maps with a single QueryRowData[] queryRows data sequence. View more documentation about this change in the section for cm.core.part.query.QueryDialogDataEnv.

The following functions in the QueryDialog have been updated, added, or removed to reflect the new index-based data retrieval versus the old key/id based retrieval.

Old: extend public str selectedRowID() {}
New: extend public int selectedRow() {}

Old: extend public PartSpecial getSpecial(str id) {}
New: extend public PartSpecial getSpecial(int row) {}

Old: extend public void putSpecial(str id, PartSpecial special) {}
New: extend public void putSpecial(int row, PartSpecial special) {}

Old: extend public void removeSpecial(str id) {}
New: extend public void removeSpecial(int row) {}

Removed: extend public str->Part parts() {}
Removed: extend public int->str rowIDs() {}
Added: extend public QueryRowData selectedRowData() {}

Other QueryDialog Changes

The following functions have been added and removed from QueryDialog in v16.5.

Added: extend public bool any() {}
Added: extend public bool empty() {}
Added: extend public bool contains(PropObj propObj) {}
Added: public bool keyCode(Window originator, KeyCode keyCode) {}

Removed: extend public bool containsSpecial() {}
Added: extend public bool any() {}
  • Checks if the QueryDialog contains any backing data
  • A quick way to see if the QueryDialog has any data
Behavior
  • Calls any() on the dialogs QueryDialogDataEnv env
  • Returns true if data contains any QueryDataRows; false if not
Added: extend public bool empty() {}
  • Checks if the QueryDialog contains any backing data
  • A quick way to see if the QueryDialog has no data
Behavior
  • Calls empty() on the dialogs QueryDialogDataEnv env
  • Returns false if data contains any QueryDataRows; false if not
Added: extend public bool contains(PropObj propObj) {}
  • Checks if the QueryDialog contains the passed in propObj in it's backing data
Behavior
  • Calls contains(..) on the dialogs QueryDialogDataEnv env
  • See documentation in the compile-time section for cm.core.part.query.QueryDialogDataEnv for more info
Added: public bool keyCode(Window originator, KeyCode keyCode) {}
  • A new override of keyCode was added in QueryDialog to intercept Ctrl+A events originating from a QueryDialog.
  • Previously, Ctrl+A would bubble up to CoreAppWindow and trigger a selectAll action on snapper elements, which was not desirable.
Behavior
  • Intercepts the Ctrl+A key combination.
    • If the event originates from a GridWindow, it returns true immediately to prevent parent handling
    • Otherwise, the event is forwarded to the query dialogs GridWindow via gridWindow().?key(CTRL_A)
  • All other key events are passed to the superclass via super(..)

Runtime/Behavior Changes

class PartMakeSpecialDialog

Changed: extend public void onOKButtonClick(Object sender, Object args) {}

The event callback for the OK button click has been modified to utilize the new generateSpecial method. It now calls generateSpecial rather than creating a special on the fly.

Old vs. New Behavior

Old:

  • Created a new PartSpecial within the event callback
  • Can easily lead to duplicated code if customization is needed for the generated PartSpecial
Old:
extend public void onOKButtonClick(Object sender, Object args) {
	PartSpecial newSpecial(partNumTF.text,
						   descrTF.text,
						   priceReplaceRB.currentState > 0,
						   amountDF.value);
	... 
}

New:

  • PartSpecial generation has been separated out into a designated function generateSpecial
    • PartSpecial can be customized here
  • The OK button click callback can now call this function along with performing its other behaviors
New:
extend public void onOKButtonClick(Object sender, Object args) {
	if (PartSpecial newSpecial = generateSpecial()) {
		...
	}
	...
}

Added: public void selectAll() {}

  • A new override of the selectAll function was added in QueryGridWindow
  • It was overridden to include the column header row on select all events
    • super() does not select this row in selectAll

Behavior

  • If grids selection mode is multi-select (isUsingMultiSelect == true):
    • Clears the seq of multiSelectedRows
    • Adds all rows from column headers (-1) to row count - 1 to multiSelectedRows
    • Invalidates and flushes grid

class QueryDialogBehavior

Changed: extend public void onSpecialChanged(Object sender, Object args) {}

Specials created or modified in the QueryDialog no longer replace the stored PartSpecial value on the PartSpecialHolder. Instead, their values are copied over to the existing PartSpecial instance.

Old vs. New Behavior

Old:

  • PartSpecials created or modified in the QueryDialog fully replaced existing PartSpecial instances
extend public void onSpecialChanged(Object sender, Object args) {
	if (sender as Window) {
		...		
		if (args as QuerySpecialChangedEventArgs) {
			dialog.putSpecial(dialog.selectedRowID(), args.newSpecial); // directly replaces existing PartSpecial
		}
	}
}

New:

  • PartSpecials created or modified in the QueryDialog copy their values over to the existing PartSpecial instance
extend public void onSpecialChanged(Object sender, Object args) {
	if (sender as Window) {
		...		
		if (args as QuerySpecialChangedEventArgs) {
			PartSpecial original = args.oldSpecial;
			original.copy(args.newSpecial); 							// copies new values to existing PartSpecial

			putSpecial(dialog, dialog.selectedRow(), original);
		}
	}
}

class EditGridCell

Added: public str clipboardValue() {}

  • An override of the GridCell function clipboardValue() has been added in EditGridCell. It returns the cells outS() value.