PBToolboxAI v5 ← Site

12. Migrating from 4.0 to 5.0 #

← Migrating from 3.0 to 4.0 · Contents · Release notes →


5.0 changes no signature of the thirty-seven components of 4.0, nor any event — except the button bar (buttonbar, 12.7) and the ue_link_clicked event of the Markdown viewer (markdownview), which receives a second argument, as_kind (12.5). Three components change words. The progress bar (progressbar) takes those of the gauges — ib_label, il_color and is_label_format disappear in favour of ib_show_value, il_value_color, is_format and is_unit (12.1). The cartesian chart (chartcartesian) writes its numbers through is_format, as the gauges and the pie chart do: of_set_value_format and of_clear_value_format disappear, and ii_point_count of a series becomes il_point_count (12.4). The crosstab (crosstab) takes the same road: of_set_value_format and of_clear_value_format disappear in favour of is_format — on the field, or on one value alone through of_value — and of ib_negative_red (12.8). The compiler shows you every line to rework. The side bar (listbar) changes one event: ue_item_rclicked also receives the screen point of the click, al_x and al_y (12.9). The tiles box (tilesbox) renames one event: ue_tile_context(as_keys) becomes ue_tile_rclicked(as_keys, al_x, al_y), and the position of of_move_tile and of_insert_tile becomes long al_position (12.12). The radial menu (radialmenu) loses four tooltip properties it never showed — is_tooltip, is_super_tooltip_title, is_super_tooltip_text and is_super_tooltip_image (12.5). The calendar (scheduler) changes three gesture events: ue_appointment_changing receives as_kind, ue_appointment_moved and ue_appointment_resized receive the values the appointment had (12.10). The shell explorer (shellexplorer) changes one event: ue_error also receives the path and a constant reason, as_path and as_reason (12.11). The rich text block (statictext) changes one event: ue_hyperlink also receives ab_opened, whether the link really opened (12.5). The tab (tab) changes one event: ue_tab_rclicked also receives the screen point of the click, al_x and al_y (12.13). The sound player (soundplayer) changes three events: ue_started, ue_ended and ue_failed also receive the number of the sound, al_sound (12.14). The toaster (toaster) changes one event: ue_toast_dismissed also receives the reason of the closing, as_reason (12.15). The web browser (webbrowser): of_go_back, of_go_forward and of_stop return a long, and under ib_veto_navigation an address typed by the user is asked about to ue_navigating (12.17). The toolbar (toolbar) changes one event: ue_item_rclicked also receives the screen point of the click, al_x and al_y (12.18). The video player (video) changes one signature: of_stop becomes a function returning a long (12.16) — a call written as a statement still compiles. Three components change a right-click event of an item, which also receives its screen point al_x, al_y: the button bar (ue_button_rclicked), the breadcrumb (breadcrumb, ue_item_rclicked) and the cartesian chart (ue_point_rclicked); the status bar (statusbar) gives that point like the others, no longer multiplied by the scale of the display (12.19). The foundation (12.20): the reason a non-visual component failed is read through of_get_last_error() — the is_last_error property disappears from crypto, restclient, soundplayer, speechout, xml, u_pbt_regex and u_pbt_zip —, and of_stop, of_close and of_reset of the non-visual components return a long.

The rest asks nothing of your code: the data grid (datagrid) and the ribbon (ribbon) gain numeric input masks, and the editor of a numeric column of the grid now opens on the text of the mask (12.2, 12.3). The new components of 5.0 are presented in the release notes.

12.1 progressbar: the words of the gauges #

5.0 brings two gauges, linear (gauge) and dial (angulargauge). A progress bar also shows a value on a scale: the library now speaks a single language for it, and the bar, which said the same thing in other words, takes the words of the gauges. No old name survives: neither a property nor a name accepted by of_set_property.

What4.05.0
Show the readoutuo.ib_label = trueuo.ib_show_value = true
Colour of the value (-1 = the theme, unchanged)uo.il_color = RGB(…)uo.il_value_color = RGB(…)
A readout that writes the valueuo.is_label_format = "{value} of {max} rows"uo.is_format = "#,##0" + uo.is_unit = "of 500 rows"
The percentage (default, unchanged)uo.is_label_format = ""uo.is_format = ""
Driving by nameof_set_property("label", …), ("label_format", …), ("color", …)("show_value", …), ("format", …), ("unit", …), ("value_color", …)
// 4.0 : the label wrote the value through placeholders
uo_progress.ib_label        = true
uo_progress.il_color        = RGB(/*red*/ 0, /*green*/ 120, /*blue*/ 215)
uo_progress.is_label_format = "{value} of {max} rows"
// 5.0 : the words of the gauges - a display format for the value, then a unit
uo_progress.ib_show_value  = true
uo_progress.il_value_color = RGB(/*red*/ 0, /*green*/ 120, /*blue*/ 215)
uo_progress.is_format      = "#,##0"
uo_progress.is_unit        = "of 500 rows"

The recipe: compile; every ib_label, il_color and is_label_format of a progress bar is reported. Replace the first two with ib_show_value and il_value_color. For the third: an empty text stays empty in is_format; a label that wrote the value becomes a format ("#,##0") and a unit; a label that wrote the percentage keeps is_format empty and puts its text in is_unit. An of_set_property that named label, label_format or color now returns -5 and does nothing (of_get_last_error names the property): search your code for these names.

12.2 datagrid: a numeric editor that types through a mask #

No signature changes, and ue_cell_edited still receives the bare number (1234.5). What changes shows on the screen: typing in a numeric column now follows an input mask, in the DataWindow syntax — the one you give through the new is_mask property of the column, otherwise its display format stripped of its literals.

What4.05.0
The editor of a cell shown $1,234.50opened on the bare number 1234.5; any character was acceptedopens on 1,234.50; the grouping appears as the digits come, the decimals are limited to the mask, letters are refused; a pasted number is read in the display language
A four-digit number under a numeric formatnot grouped in some languages (1234 in Spanish)grouped in every language (1.234 in Spanish)
A negative number rounded to zero-00
Opening then closing the editor without typingcould change a value the format roundschanges nothing
A rating cell read by a screen readerfive star signs4 / 5
// 5.0 : the input mask of a numeric column - the cell still receives the bare number
uo_grid.of_column(/*key*/ "revenue").is_mask = "#,##0.00"

The recipe: nothing to change. Code that read the typed text never sees it: ue_cell_edited still gives the number. A column whose input must stay free (a code, a part number) is a text column, not a numeric one.

12.3 ribbon: the masks of a spinner #

Nothing changes for a spinner without a mask. Two new properties of its handle, in the PowerBuilder syntax: is_mask, the input mask ("#,##0.00", "0%"), and is_format, the display format with its literals (0 "pt" shows 11 pt, typed 11). id_value and ue_value_changed keep the bare number, the swap between the two raises no event, and the masks follow the spinner into the panel of a collapsed group.

// 5.0 : a font size shown "11 pt", typed "11"
uo_ribbon.of_item(/*keys*/ "home/font/size").is_format = "0 ~"pt~""

The recipe: nothing to change.

12.4 chartcartesian: the number format through is_format #

The cartesian chart wrote its numbers through a function with four arguments (decimals, prefix, suffix, thousands separator). 5.0 puts the charts and the gauges under one language: a PowerBuilder display format, the one of a DataWindow column, in the is_format property — of the whole chart, and of an axis through its handle. The sections positive;negative;zero, the literals and the percentage come with it, and the separators stay those of the display language. No old name survives.

What4.05.0
The format of the chartuo.of_set_value_format(0, "$", "", true)uo.is_format = "$#,##0"
The format of one axisuo.of_set_value_format(AXIS_VALUE2, 1, "", " u", false)uo.of_axis(AXIS_VALUE2).is_format = '0.0" u"'
Back to the number as it isuo.of_clear_value_format()uo.is_format = "" (and "" on each axis that has its own)
Driving by name—of_set_property("format", "#,##0")
The number of points of a series (read only)uo.of_item("k").ii_point_count (integer)uo.of_item("k").il_point_count (long)
// 4.0 : decimals, prefix, suffix and thousands as four arguments
uo_chart.of_set_value_format(/*decimals*/ 0, /*prefix*/ "$", /*suffix*/ "K", /*thousands*/ true)
uo_chart.of_set_value_format(/*axis*/ u_pbt_chartcartesian.AXIS_VALUE2, /*decimals*/ 1, /*prefix*/ "", /*suffix*/ " u", /*thousands*/ false)
// 5.0 : a display format, written as in a DataWindow - for the chart, then for one axis
uo_chart.is_format = "$#,##0K"
uo_chart.of_axis(/*axis*/ u_pbt_chartcartesian.AXIS_VALUE2).is_format = '0.0" u"'

The recipe: compile; every of_set_value_format and of_clear_value_format is reported. Write the format as in a DataWindow: decimals gives the number of 0 after the point (-1 = #,##0.###), thousands the grouping ,, the prefix and the suffix are written before and after (in quotes when they hold digits or spaces). The format of an axis goes into of_axis(<axis>).is_format.

12.5 Other behaviours you may see #

What4.05.0
Native menus of a component that has an accent of its own (il_theme_accent)the accent only showed in the box of a checked entrythe pointed entry shows it too, as a stripe on its start edge (on the right in RTL)
button: Ctrl, Alt or Shift + Enter (and Ctrl / Alt + Space, Ctrl + Esc) on the button that has the focusclicked that buttongo to the window, as from any other control: the shortcut of another button (is_shortcut = "Ctrl+Enter") fires, the focused button does not; Enter and Space alone still click it
Grayed button with ib_default (or ib_cancel), closest to the focus, in an MDI sheetEnter (Esc) went to the default button of another sheetthe key stays in its sheet: the field, or the default PB CommandButton, receives it
breadcrumb: ii_max_visible setan exact number of segments under OVERFLOW_COLLAPSE (the width folded nothing more), ignored under OVERFLOW_SCROLL and OVERFLOW_SHRINKa ceiling in all three modes; under OVERFLOW_COLLAPSE the width still folds more when the bar is too narrow, and where you are no longer leaves the bar
breadcrumb: of_add_child with an empty textan empty line in the menuthe branch key, as of_add_children does
breadcrumb: Ctrl+S, F5 and the other shortcuts of the window while the path is typeddid not firefire, as from a SingleLineEdit; Enter and Esc stay with the field
breadcrumb: ue_children_needed that never returnsno chevron opened any more until the next of_reseta click on another chevron abandons the question, and the trail lets it go after 10 seconds
chartcartesian: a band or a threshold without a colour (-1 or NULL)a solid block of the text coloura pale wash of the theme accent (a threshold line: the accent); a NULL bound is refused (-5)
chartcartesian: a NULL weight in a heat mapthe cell painted in the hottest colour, labelled "NaN"an empty cell: nothing drawn, labelled or clickable there; a bubble without a weight keeps the default size, outside the scale
chartcartesian: of_remove_seriesthe following series changed colour; the tooltip of the removed series dressed the next series with the same keyevery series keeps the colour taken when it was added; the tooltip and the item colours go with the series
chartcartesian: of_append_values / of_append_categories with ib_animatedthe whole chart fell back on its axis and rose again at every push, as long as the window was not fullonly the new shape rises, the others slide; the whole arrival only replays when a series is added
chartcartesian: stacked bars on both value axesthe two stacks were drawn on top of each otherside by side in the category
chartcartesian: a markup tag in a category or a value labelwritten as it stands on the axis, read as markup in the paneltext everywhere: the tag is dropped (the axis, the panel, #x#, #label#)
chartcartesian: Esc with nothing open, Enter on a gapkept by the chartgo to the window: its Cancel button, its default button
codeeditor: Ctrl+Tab or Alt+Tab in the editorindented the code: the keyboard could not leave the editorgo to the window (the next page of a tab); Escape then Tab leaves the editor, Ctrl+M or ib_tab_moves_focus let Tab out
codeeditor: of_find on an invalid regular expressionreturned 0returns -5, as of_replace does
codeeditor: a new is_text during a searchthe bar stayed open and raised ue_find_resultthe bar closes, raising nothing (a value is silent)
codeeditor: is_syntax = "SQL" read back"sql""SQL", as written
Folded codeeditor: #regionopen, the copy and of_selected_textshown as #region; the copy gave the display, without the lines of the closed regionsshown as written; the copy and of_selected_text give the source of the range, closed regions included
codeeditor: markers and il_doc_line when lines are added or removed above themstayed on the same line numbermove with their line; a deleted line takes its markers with it
codeeditor: the caret after "Replace all" (of_replace_all)on the last replacementstays where it was, moved by what was inserted before it
codeeditor: Ctrl+Z, Ctrl+Ythe browser's history, lost when the text was written with the focus elsewherethe history of the component (of_undo, of_redo): it also counts what your code does, a new is_text empties it
crypto: of_totp_verify(secret, code, ref al_step) on a code typed with spaces ("864 010")refused, step 0accepted, as by the two-argument form; the spaces are ignored
crypto: of_base64_encode_file of a 32 to 64 MB file in a 32-bit applicationpromised up to 64 MB; the memory of the process could run out"" and of_get_last_error() (32 MB at most in 32 bits); of_base64_encode_file_to_file encodes a file of any size to another file
crypto: of_totp_uri of a secret typed by hand ("gezd gnbv", a "0")written as it stood in the URIwritten in base32 capitals, without spaces or =; any other character: "" and of_get_last_error()
crypto: a NULL argumentis_last_error could come back NULLcounts as an empty one; of_get_last_error() is never NULL
crypto: a target \x or C:x (of_base64_decode_to_file, of_encrypt_file, of_decrypt_file)-5 and a wrong message ("not a base64 value", "all needed")-5, and of_get_last_error() says the path depends on the current folder of a drive
commandpalette: a search and the recently used commands (is_recent)a recent command gained up to il_max_recent × 4 points: with a large limit, it passed a better matchit only breaks ties between results that match about as well
commandpalette: a command without a group (as_group = "") declared between two groupslisted under the header of the group declared before itfirst in the list, without a header
commandpalette: Home / End in a search box holding text, Shift+Homemoved the selection in the list; Shift+Home selected nothingmove the caret in the box; Ctrl+Home / Ctrl+End reach the list; Shift selects in the box
commandpalette: a right or middle click on a lineran the commanddoes nothing
commandpalette: of_command on a key no command hasib_enabled / ib_visible read true, a write was lost in silencethey read false; a write is lost and of_get_last_error says so
commandpalette: a second palette object that took over a chord is destroyedthe key answered nobody until the first one registered it againthe chord comes back to the first one
commandpalette: is_recent with spaces or repeated keys, a lower il_max_recent"a, b" kept only a; a twin showed twice; is_recent stayed longcleaned, cut to the limit and given back clean to is_recent at the opening
dockcontainer: building the dock, restoring a layoutue_layout_changed at every add, the first one knowing a single panel: a layout saved in the event was overwritten by a half-built oneonce for a burst framed by of_set_redraw(false) … (true), at the resume (and for changes less than 40 ms apart); of_set_layout raises it once. Read the saved setting before creating the panels
dockcontainer: the panel at the front of a stack changes without a click on its tabnothing was raised (a panel stacked by of_add_panel or of_move_panel, the front one closed, floated or removed, a panel docked back)ue_panel_selected of the panel that came to the front, after ue_panel_closed, ue_panel_floated or ue_panel_docked; a restored layout raises none. n_pbt_dock_panel.ib_front reads it back
dockcontainer: ib_visible = true on a closed panel of a stackit came back behind the active tabit comes to the front, and ue_panel_selected follows; in an unpinned group it stays on the rail
dockcontainer: of_move_panel towards the panel itself (as_target = as_key)returned 0 doing nothing, or split its stackreturns -5; to split a stack, aim at another panel of the stack (of_move_panel("b", "a", POSITION_BOTTOM))
dockcontainer: a panel moved into an unpinned group, or out of itib_pinned changed without an eventue_panel_pinned follows
dockcontainer: a click without a move on a splitterraised ue_layout_changedraises nothing: nothing changed
dockcontainer: of_keys_at with numeric keysthe integer keys first (2, 10, zeta)the add order (zeta, 10, 2)
dockcontainer destroyed at run time (CloseUserObject)its controls came back on the window, hiddenthey get back the visibility they had before of_add_panel
dockcontainer: of_add_panel of a control that CONTAINS the dockthe windows looped into each otherreturns -5, the control stays where it was
crosstab: AGG_COUNTcounted the rowscounts the non-empty values, like Excel's Count; AGG_COUNT_ROWS, new, counts the rows
crosstab: a sum with no value at all; a "difference from the previous one" next to an empty cell0an empty cell (of_get_cell_value gives NULL)
crosstab: Top N or Bottom N (of_set_value_filter, or the menu) on a field placed under another one of its zoneranked over the whole tableranked inside each parent (the best city of each region); at the first level, unchanged; the members tied with the N-th one all stay
crosstab: no field in Columnsa total column that doubled the only column (`Nord650650`)no total column any more; ib_col_grand_total keeps its value
crosstab: several measures and fields in Columnsone Total column per measure, with no measure name, and not sortablea "Total" header then one header per measure, sortable
crosstab: ue_layout_changedraised by the user's gestures, and by is_thousands and of_remove_field onlyalso raised by every order of the code that changes what of_get_layout returns (of_set_layout included), once per order; only once at the end of a build framed by of_set_redraw(false) … (true); never when nothing changes, nor for of_reset
crosstab: a percentage (SHOW_PCT_*)57.9 % in every languagewritten the way the display language writes it: 57.9% in English, 57,9 % in French
crosstab: the label filteroffered by the chip menu of a numeric field only; on a date, of_set_label_filter compared the year (2025-03-15 was 2025)offered for every field; on a date, the text overload takes days: LABEL_BEFORE, LABEL_AFTER, LABEL_BETWEEN ("yyyy-mm-dd", days included); the numeric overload, or LABEL_CONTAINS / LABEL_BEGINS / LABEL_ENDS, on a date: -5
crosstab: of_group_date_field on a field that holds no dates0, and a single "(blank)" member-5
crosstab: of_add_calc_field / of_add_calc_measure refused by the grid (name already taken, formula that does not compile)0; only ue_calc_field_error said so-5 and the reason in of_get_last_error (ue_calc_field_error is still raised); a name holding / or `: -5; a formula accepts .5 and 1e3`
crosstab: of_set_value_filter Top or Bottom of less than 1 member; of_expand_to_level below 1brought back to 1-5
crosstab: of_get_cell_value called from an event raised during an order of this script-2, as for a component not created-4, and of_get_last_error says why: read after the event
crosstab: the Options menu of the grid (the gear)"Grand total" and "Subtotals" switched both axes from the state of the rowsone entry per axis: grand total row and column, row and column subtotals
crosstab: of_from_datastore — a CHAR column, a decimal, the Format of a columnthe padding blanks stayed in the member; the Format was ignoredthe padding blanks are removed; a decimal is read with the separator of the workstation; the Format of the column is the default format of its values
datagrid: a selected row the search or a filter hides, or of_remove_row removesstayed selected, silently (of_selected_keys and ue_row_menu_clicked carried it)leaves the selection, and ue_selection_changed says so; of_select_rows does not take a hidden row
datagrid: ib_hidden, is_pin, ii_index set to the value they already have; a click on the grip without draggingraised ue_layout_changedraise nothing: nothing changed
datagrid: layout changes between of_set_redraw(false) and of_set_redraw(true)one ue_layout_changed per changea single one, on resuming, with the final layout
datagrid: a type or a renderer outside the constants (of_add_column, is_renderer, is_selection_mode); of_add_row_menu_item without a created componentaccepted and read back as they were, without effect; 0of_add_column returns -5 (of_get_last_error says which); an unknown renderer reads back "", an unknown mode SELECT_NONE; -2
datagrid: of_reload_row or of_update_row of an edited cellthe "modified" mark stayedit goes: the row holds what the DataStore holds again
datagrid: editing a column with a code table, a date; a time column of a DataStorethe engine's <select> and date box; a time was textthe library's list and calendar (a date can be TYPED too, in the order of the language); a time (TYPE_TIME): sort, filter > 09:00, format, typed 9:5
datagrid: a filter > 3 on a rating without a type or on a column with a code tablelooked for the text "> 3": no rowcompares the data (the number, the code)
datagrid: a tree under a search; a row whose parent is not in the gridthe child found stayed hidden; the row never showedits ancestors are shown, open; the row hangs from the root
datagrid: of_from_datastore / of_load_rows after of_open_source; of_append_rows without a key after of_from_datastore; a CHAR valuethe grid stayed on skeletons; the row was refused (-5); kept its padding of spacesthe source is left; the key follows the largest RowID; trimmed
datagrid: of_export_xlsxdates were written as text; no ceilingreal Excel dates; a workbook too large (beyond about 18 MB) is refused, ue_xlsx_saved says why
messagebox: Esc or Alt+F4 on a box without a cancel buttonclosed the box and returned 0 — of_info too, which promised 1as on Windows: a box with a single button closes through it (of_info returns 1), a Yes / No box does not close — it has to be answered; ib_closable = true gives the 0 of 4.0 back. A = 2 test migrated from a MessageBox no longer lets a deletion through
messagebox: a shortcut (of_info, of_error, of_confirm, of_prompt…) after setting il_accent, is_position, ib_movable, a size or ib_input_passwordeverything was cleared silently: the password of of_prompt showed in clearthe shortcut only replaces the content (title, message, icon, buttons, checkbox, choices); the appearance and the settings of the field stay. of_reset() clears everything
messagebox: of_reset() after a boxof_get_last_error, of_checked, of_action and of_input_value still spoke of the old boxthey are reset
messagebox: a required field filled with spacesacceptedempty: the default button waits (the value typed comes back as it is)
messagebox: an [action] zone in the title, a label or the footer; a link in a choice; two buttons with the same mnemonicthe zone did nothing; the link opened the browser AND chose; Alt+letter answered with the first buttonthe zone answers as in the message (of_action); the link opens without choosing; Alt+letter moves the focus from one button to the other, Enter picks
messagebox: Ctrl+Clost the & of &&, copied the tags of a button, ignored the inputthe labels as shown, "label: value" of the field (never a password), the details and the footer
messagebox: a descendant that called xx_set_style_override or xx_clear_style_override (protected)overrode a theme token of the boxthey are gone: il_accent colours the box
json and jsontree: a path level that holds ~0 or ~1read as written; a key that holds / had no path~1 is a / of the key, ~0 a ~ (JSON Pointer, RFC 6901): paths/~1users reads the key /users; a key that holds a ~ is written ~0 in a path
json: an empty path level (a//b, a/) or a path that starts with /refused with -5, read as absentan empty level is the key "", a leading / is the full pointer form: /name is name, / names the key "" of the root
json: of_get_number, of_get_decimal, of_get_longlong on a string such as "12 kg" or "1,5"read its beginning: 12, 10: a string counts only when all of it is a JSON number — "12.50" still reads 12.5
json: of_set_members of a key the document already holdsthe key was written a second time: n_pbt_json read the first one, a browser or a server the last onethe value is replaced in place; a key the fragment repeats keeps its last value
json: of_pretty of a document holding an of_set_raw value nested more than 512 levels deepanother document, cut at 512 levelsan empty text
jsontree: a click on a key that holds /, an empty key, or under a duplicate keya path that read ANOTHER value in n_pbt_jsonx~1y for the key x/y, a//b for an empty key; of_selected_addressable returns false under the second of two identical keys
jsontree: Ctrl+C with a piece of text highlighted with the mousethe whole nodethe highlighted piece
jsontree: a JSON text that starts with a BOMrefused (ue_error)shown, as n_pbt_json reads it; is_json reads back as set
jsontree: the ue_error message in EnglishInvalid JSON : …Invalid JSON: … (each language keeps its punctuation); 01, 1., 1e say Bad number
jsontree: of_expand_path during a searchfolded again at the next step of the search, without ue_node_toggledstays open, with the blocks opened above it
jsontree: Space on a selected valuescrolled the tree by a pagedoes nothing (a block still folds)
xmltree: a blank between two children (<b>x</b> <i>y</i>)had no line: /p/text()[1] answered -5a line of its own, shown ␠, with its path: the line numbers of mixed content change
xmltree: a text between two children (Hello <b>x</b> again)Hello, again: its edge blanks trimmedHello , again: only the layout line breaks go
xmltree: of_select_path of an XPath whose first node is a blank of layout (//text())-5the first node the tree SHOWS is selected
xmltree: of_selected_value of an element that holds only line breaks (shown <x/>)""those line breaks, as n_pbt_xml reads them
xmltree: Ctrl+C with a piece of text highlighted with the mousethe XML of the whole nodethe highlighted piece
xmltree: the ue_error message in EnglishInvalid XML : …Invalid XML: … (each language keeps its punctuation)
xmltree: of_expand_path during a searchfolded again at the next step of the search, without ue_node_toggledstays open, with the elements opened above it
xmltree: Space on a selected leafscrolled the tree by a pagedoes nothing (an element with children still folds)
jsontree, xmltree: a search that closes (Escape in the box, of_clear_search, of_reset, ib_search_enabled = false)no event: an application's "3 / 12" line stayed wrongue_search_result(0, 0), once; nothing when no search was running
PBT_SetDefaultFont with a size: codeeditor, jsontree, xmltree, ribbon, toolbar, crosstab, datagrid, tilesbox, stepbar, listbar, dockcontainer, video, picture, menus and tooltipsthe code, the document, the ribbon (its theme size) and many secondary texts kept their sizethey follow the size of the application, in their proportions; the size of the application wins over the ribbon size of the theme; an ii_font_size of the codeeditor wins over both
markdownview: ue_link_clicked(string as_url)(string as_url, string as_kind): a script already written for the event stays valid; as_kind (LINK_WEB, LINK_MAIL, LINK_DOCUMENT, LINK_FILE, LINK_OTHER) says what the link is — sort by it rather than by the text of the address
markdownview: a picture of a document on a network shareloadedrefused, unless it lies on the share the document was read from, or with ib_network_pictures; a document read from the web shows no file of the workstation
markdownview: a new is_markdown of the same document, of_refreshthe view jumped to the topthe reading position is kept; a new is_source still starts at the top
markdownview: of_toc, of_scroll_to and a search right after is_sourceacted on the previous documentthe file is read in the background: of_toc returns 0, of_scroll_to and the search wait for it; read the table in ue_loaded
markdownview: a column the author aligned (:--, --:) in a right-to-left applicationchanged sideskeeps its side; only the default alignment follows the direction
markdownview: ue_load_failed for a text set by is_markdownnever raisedraised (REASON_FAILED, empty as_source) for a text the component cannot read; the previous document stays on screen
menubar: the shortcut of an entry (is_shortcut)acted on the state the last opening of its menu leftraises ue_menu_opening of its menu first, as Windows does: an entry that event greys does not answer, and ue_menu_closed says so
menubar: an opening given up before it showed (sliding fast, Escape or Alt during ue_menu_opening, the focus lost)ue_menu_opening without ue_menu_closed; after Escape the dropdown opened anywaynothing opens, and ue_menu_closed follows: every ue_menu_opening gets exactly one ue_item_selected or one ue_menu_closed
menubar: Alt then Escape, F10 then EscapeEscape went to the window too: its Cancel buttonEscape leaves the menu mode and stays with the bar
menubar: a menu opened from the keyboard (Alt+letter, F10 then Enter)no item highlighted: Enter chose nothingthe first item is highlighted, Enter picks it
menubar: Alt when the bar already has the focusthe menu mode toggled on the key down: Alt+Shift (keyboard layout) turned it onwhen Alt is released alone, as on Windows
menubar: a click on a greyed title or on the empty part of the barthe bar kept the keyboard, the field being edited lost itthe keyboard stays with the control the user was typing in
menubar: is_shortcut set on an address that names no entrythe key was taken in the whole window, even after of_clearnothing is armed: set it after of_add_item
pdfviewer: ib_allow_save / ib_allow_print of one viewerapplied to every viewer of the application; an of_reset elsewhere gave Save back to a confidential documenteach viewer keeps its own setting
pdfviewer: ib_allow_save / ib_allow_print set before is_sourcethree loads, three ue_load_completed; a document that failed was tried again at each changea single load; a document that failed is not tried again
pdfviewer: ii_page set while a document is shown, then another is_sourcethe next document opened at that pagethe page was the shown document's: the next one opens at its first page; to open a document on a page, set is_source then ii_page
pdfviewer: the same value set again (ii_page, ii_zoom, is_fit, ib_viewer_toolbar)reloaded the document and raised ue_load_completeddoes nothing
pdfviewer: ii_zoom outside 25 to 500passed to the reader as isbrought back into 25 to 500, read back as applied
pdfviewer: an https://name:secret@… address; a source made of blanksput in the reader, which refused it under a vague reason, the secret travelling back in the events; read back as is, of_refresh returned 0refused at once through ue_load_failed (REASON_UNSUPPORTED): download the document with the restclient; read back "", of_refresh returns -4
picture: id_max_zoom on a picture larger than its framethe wheel, + and id_zoom went up to the actual sizethey stop at the ceiling; only the 1 key goes beyond
picture: a new is_source, or ib_zoomable = false, on a zoomed picturethe zoom came back to 1.0 without a wordue_zoom_changed(1.0) is raised (of_reset stays silent); set id_zoom after is_source
picture: a path with blanks around it (a CHAR column)refused, REASON_UNSUPPORTEDdisplayed; is_source reads back as written
picture: the zoom keys with Ctrl, Alt or Windows held downCtrl++ zoomed, Alt+1 showed the actual sizeleft to your application (shortcuts, mnemonics)
picture: a recoloured picture (mono:, tint:) from another site whose server refuses cross-origin requestsue_loaded and an empty frameue_error with REASON_FAILED, the message says why
radialmenu: is_tooltip, is_super_tooltip_title, is_super_tooltip_text, is_super_tooltip_imageexisted, never showed anything: the launcher has no surfaceremoved: the compiler shows the line, delete it
radialmenu: of_close, a second of_show, of_clear or of_reset while a wheel is openue_dismissed came when the wheel left the screen; of_is_open stayed true until thenue_dismissed at once, once per opening; of_is_open false as soon as the call returns
radialmenu: of_remove_item of a branch the open wheel does not show (hidden)the wheel closed (ue_dismissed)the wheel stays open; it closes only when it showed the branch
radialmenu: of_remove_item with a bare key ("csv")-5resolved as of_item does it (the one branch that carries it); -5 when two branches share it
radialmenu: of_show of a wheel with nothing to show while another is openue_dismissed, and the old wheel stayed on screenthe old wheel closes too: one ue_dismissed for each opening
radialmenu: il_back_color_hover of a branch without il_text_color_hoverthe pointed label kept the text of the theme (white on pale pink in a dark theme)a text readable on that tint is chosen; a colour you set is never changed
restclient: ib_windows_auth or is_client_certificate, and a redirection to another hostthe Windows credentials and the certificate followed the redirectiononly the host and port of the request receive them: the other host gets the request without them
restclient: a header value beyond Latin-1 (Greek, Japanese…)accepted by of_set_header (0), then every request of the object returned -5refused by of_set_header itself (-5, of_get_last_error() says why); of_set_basic accepts them: its pair leaves as the base64 of its UTF-8
restclient: a malformed method ("GE T"), credentials in the URL (https://user:pwd@…), an of_upload field name holding a quote-4 "request failed: 0"; the credentials vanished without a word; the multipart body was broken-5, and the reason in of_get_last_error() (for credentials: use of_set_basic)
restclient: a 303, or a 301 or 302 after a POST, that goes on as a GETkept the Content-Type of the original bodygoes without Content-Type
restclient: ue_progressraised for every async body, never reaching the total: a progress bar stayed at 39 %raised for every async body (the documentation says so), and the last one, just before ue_response, is the total
restclient: of_response_header of a header sent several times (Link, Set-Cookie)the first value onlyall of them, joined by , — Set-Cookie by a line break
restclient: the User-Agent sentPBToolboxAI/4.0, written in the codethe version of the library; of_set_header("User-Agent", …) still replaces it
restclient: a request when the HTTP client could not be createdleft on a one-off session, without Windows authentication, client certificate or cookies-2, and il_status says so
restclient: of_set_header("Authorization", …) after of_set_basicboth authentications were sentone authentication at a time: the Authorization set replaces the Basic one
ribbon: a value written by the code (is_text, id_value) while the field of a combo or a spinner has the focusthe field kept the old text; leaving it raised ue_combo_changed / ue_value_changed with the old value, which replaced yoursthe field shows it at once, unless the user is typing (the typing wins); leaving the field without typing raises nothing
ribbon: a label with tags (is_label, the title of a tab, a group, a banner, the application button)shown as typed, tags included (the panel of a folded group did interpret them)the rich text markup is interpreted everywhere; a text of your user goes through of_escape_markup
ribbon: the wheel over the ribbonevery small move of a touchpad changed tab; a folded ribbon changed tab too, showing nothingone tab per notch of the wheel (small moves add up); nothing on a folded ribbon
ribbon: of_add_spinner with a step of 0 or less, or a minimum above the maximum; inconsistent id_min / id_max / id_stepaccepted: dead or reversed arrows, a value outside the range shownof_add_spinner returns -5 and keeps the value within the range; a step of 0 or less is refused (of_get_last_error says why); a bound written past the other one takes it along, as in a NumericUpDown — the order of the two writes no longer matters
ribbon: an is_keytip not made of letters A-Z and digits ("É", "-")kept and read back, never reachable from the keyboardrefused: nothing changes, of_get_last_error says why
ribbon: Escape at the second level of the key tips (the commands of a tab)closed all the key tipsgoes back to the letters of the tabs, as in Office; a second Escape closes
speechout: of_speak_from(0) or a negative numberread from the first sentence-5, nothing is read (positions count from 1)
speechout: ii_rate, ii_pitch, ii_volume set out of their range (ii_rate = 1000)read back the value set (1000) while the voice applied the boundread back as applied (400)
speechout: a [rate]…[/rate] piece in a sentencea sentence of its own: its own ue_sentence, its own number, and a full stop after [/rate] became a "sentence"stays in its sentence: one ue_sentence with the whole text, one number, ue_word counts in that text, of_spoken_text one line per sentence; the punctuation goes with the piece
speechout: [rate=0]read at 100 %the slowest rate, 10 %
speechout: a rule of of_add_replacement on a word that is also the name or the value of a tag (total with [mark=total], rate, a word inside [spell])rewrote the tag: the mark changed its name, the tag was read aloud, the spelled text changedthe rule rewrites the text between the tags only
speechout: a workstation with no voice at allue_error, then a reading "under way": ue_started, every ue_sentence, ue_stopped; of_speak_sync returned 0ue_error and nothing else: no reading, no ue_started; of_speak_sync returns -4
speechout: is_lang without a region ("fr", "en")ue_voice_fallback at every readingno fallback for a voice of that language, whatever its region
speechout: of_clear_queue behind an of_speak (the reading under way is not a text of the queue)ue_queue_done at the end of the readingno ue_queue_done: no text of the queue was read
speechout: an initial (John F. Kennedy), an abbreviated month (Oct. 10), a dotted acronym (U.S.)ended the sentencestays in the sentence (a month or an acronym ends it before a capital, like etc.): the sentence numbers may change
statusbar: a clickable panel that is greyed and carries a tooltipthe tooltip never showedit shows, to say why the panel is greyed
statusbar: of_count, of_keys_at, of_has on the address of a panel ("enc")0, "", false: the entries of its list were not seenthe entries of its list, separators left out
statusbar: a position in a drop-down list (of_insert_menu_item, of_move_menu_item)counted the separatorscounts the entries only, like the positions of the panels
statusbar: a panel or entry key that starts with __acceptedrefused, -5: it is reserved to the component
statusbar: is_tooltip and the five colours on a list entry (of_menu_item)kept and read back, without effectignored, read back empty (-1 for a colour): the native menu does not show them
statusbar: the grip (ib_show_resize_grip) in an MDI sheet, or a bar that is not at the bottom of its windowit resized the frame, from its cornerit resizes the sheet; no grip when the bar does not sit in the bottom corner
statusbar: the Menu key or Shift+F10 on a focused panelnothingue_panel_rclicked, at the bottom-left corner of the panel
stepbar: Enter or Space on a step, in a window that has a Default buttonue_step_clicked and the Default button ("Next") firedue_step_clicked only: the key stays with the bar
stepbar: of_clear_steps while the bar stands on a stepraised nothingue_step_changed(rank left, key left, 1, ""), like the removal of the current step; of_reset raises nothing
stepbar: ii_current beyond "everything done" (further than the number of steps + 1)ue_step_changed announced at once a rank that did not exist; the arrival of the step was silentnothing is raised while the bar waits; ue_step_changed is raised when the step arrives
stepbar: of_move_step on a bar that stands on "everything done"could reopen the bar: a step became current again, with ue_step_changedthe bar stays on "everything done", nothing is raised
stepbar: NAV_VISITED, a step inserted or moved in front of the current stepclickableshown done, but not clickable: it was never reached
stepbar: a step with a warning (STATE_WARNING)an amber bulletan amber bullet and a second amber ring: it no longer looks like a done step where the accent is amber
statictext: ue_hyperlink(string as_url)(string as_url, boolean ab_opened): a script already written for the event stays valid; ab_opened is FALSE when the link did not open (a scheme other than http, https, mailto — of_get_last_error() says why —, or kept shut by ue_hyperlink_opening)
statictext disabled on a background of its own (il_back_color, a [bk] run)the text took the theme's grey, unreadable on a dark or coloured backgroundits colours are kept and attenuated; on the theme's surface, the theme's grey, as before
statictext: PBT_SetDefaultFont with a sizethe size stayed 11 ptthe size given applies (11 pt without it, unchanged)
statictext: ii_font_size outside 6 to 200applied as it wasbrought back to the nearest bound, like the [size] tag, and read back as applied
statictext: double click on a word with ib_selectableone ue_clicked before ue_double_clickedtwo ue_clicked then ue_double_clicked, as the PowerBuilder StaticText; releasing after a drag that selects still raises no click
statictext: of_reset of a text announced cutnothingue_text_overflow(false)
statictext: is_text read after of_append_text, when a line left a tag open[b]Start[br]two: set again, the bold ran on into the next line[b]Start[/b][br]two, what the screen shows; an empty line keeps its height; under ib_marquee, the lines scroll as one line
statictext: ib_auto_width and an emptied textkept the width of the previous textshrinks to its padding; a theme change measures the width again too
xml: of_count, of_get_values, of_get_attrs, of_get_attr_names when nothing is loaded, a built element is still open or the engine refuses the XPathreturned 0, like a search without resultreturn -4 (-2 when the page does not answer), of_get_last_error() says why; 0 is always a true zero. A > 0 test does not change; an = 0 test that meant "nothing found" now sees the refusal apart
xml: of_get_attr and of_remove_attr of an absent attribute, of_get_attrs with an empty nameempty with no reason, 0 ("done"), 0empty and "no such attribute" in of_get_last_error() (an attribute written empty stays without a reason), -4, -5
xml: of_set_value, of_set_attr, of_add_child of a text holding a control character (Char(1)) or a CRwritten as it was: the document no longer reloaded, the CR came back as LFthe forbidden character is dropped, as the builder does; the CR is written &#13; and reads back
xml: builder — a second element at the top, a text with no element open, an attribute after a childwritten (two roots) or ignored without a wordleft out, and of_get_last_error() says why
xml: of_get_value("sum(//qty)") over a text that is no number; of_get_value("/")the text NaN; emptyempty and "the expression is not a number"; the text of the document

The recipe: nothing to change.

12.6 What was added #

None of the following asks you to change your code. The eight new components of 5.0 are presented in the release notes.

ObjectAdded
progressbaris_unit: a text written after the readout ("of 500 rows", "MB")
datagridis_mask of a column (n_pbt_datagrid_column): the input mask of a numeric column; a column without a display format shows its is_mask
datagridthe keyboard of the headers (Arrow up from the first row; Enter sorts, Shift+Enter adds to the sort; Alt+Down or the Menu key opens the menu of the column; Ctrl+Shift+arrows move it, Alt+arrows change its width); TYPE_TIME; of_get_last_error says why a call returned -5
ribbonis_mask and is_format of a spinner (n_pbt_ribbon_item); is_group: exclusive toggles of a group (n_pbt_ribbon_item) and radio entries of a menu (n_pbt_ribbon_menu_item); ue_item_rclicked (right click on a control, a group, a tab or a Quick Access Toolbar button, with the screen point al_x, al_y; the Menu key and Shift+F10 too) and ue_rclicked (outside any item); is_title of a contextual group (n_pbt_ribbon_ctx_group), whose tooltip shows on the banner; key tips of the Quick Access Toolbar buttons; item colours of the menu entries and the Quick Access Toolbar buttons; accessible names of every control
breadcrumbtyping the path becomes an address bar: ib_auto_complete, ue_path_typing and of_add_suggestion (completion while typing), ib_veto_path, ue_path_entering and is_path_error (a refused path keeps the typing)
chartcartesianof_from_datastore (DataStore, DataWindow, DataWindowChild), of_map and the ROLE_* constants, of_reload: the graph of a DataWindow (rows summed by category and series, read again in place); of_set_point_color / of_get_point_color; ue_point_rclicked, ue_rclicked; of_get_categories; of_remove_axis_section
codeeditorof_undo, of_redo, ib_can_undo, ib_can_redo and ue_undo_state_changed (the undo history under control); ue_modified_changed; of_toggle_comment (Ctrl+/); of_next_marker (F8); ib_match_brackets; ib_tab_moves_focus (Ctrl+M)
cryptoblobs (of_base64_encode_blob, of_base64_decode_blob, of_hash_blob, of_hmac_blob, of_crc32_blob, of_encrypt_blob, of_decrypt_blob); of_base64_encode_file_to_file; of_jwt_verify_jwks, of_jwk_to_pem, of_pem_to_jwk; the expected claims of of_jwt_verify and il_jwt_leeway_seconds; JWT_HS384/HS512, JWT_RS384/RS512, JWT_PS256/PS384/PS512, JWT_ES384 and KEY_EC_P384; the scheme and hash of of_sign / of_verify (SIGN_PKCS1, SIGN_PSS); the additional data of of_encrypt_with_key / of_decrypt_with_key; the hash of of_rsa_encrypt / of_rsa_decrypt; the settings of of_totp_code, of_totp_verify, of_totp_uri and of_hotp_code; of_password_needs_rehash
buttonbaris_style of a button (STYLE_PRIMARY, STYLE_FLAT, STYLE_DANGER), is_badge (a text badge), il_badge_color, is_mnemonic, ii_image_size and ii_badge_size of the bar, ib_enabled of the whole bar, ue_button_rclicked and ue_rclicked, of_clear_shortcuts
commandpaletteof_load_menu(menu): the palette filled from a PowerBuilder menu, read again at every opening; of_loaded_item(as_key) gives the item of a command; of_get_last_error()
dockcontainerib_front of a panel (n_pbt_dock_panel, read only): the panel its stack shows; the Auto Hide entry of the panel menu, also on the rail handle; Shift+F10 and the Menu key open that menu under the tab; the active panel, the one holding the keyboard: of_active_panel() and ue_active_panel_changed(as_key)
crosstabof_value(position) and its handle n_pbt_crosstab_value (one value of the Values area: is_agg, is_show, is_conditional_formatting, is_format, ib_negative_red, is_label, of_field()); of_value_count, of_remove_value, of_move_value; of_get_cell_rows (the rows of the DataStore behind a cell); is_format of a field; AGG_COUNT_ROWS, LABEL_BEFORE, LABEL_AFTER
messageboxof_messagebox (the arguments of MessageBox(), Question! and YesNo! included) and the BUTTONS_* constants; of_retry_cancel; the default button of of_confirm, of_yes_no, of_yes_no_cancel (al_default); Retry, Abort, Ignore, Close translated; ib_closable, ib_sound; is_details, is_details_label; is_footer, is_footer_icon; ib_input_multiline, il_input_max_length, is_input_pattern, is_input_error; of_prompt that masks and requires; a disabled choice (of_add_choice, ab_enabled)
jsontreeof_get_layout, of_set_layout and ue_layout_changed (the folds, the selection, the line at the top); of_selected_addressable, of_selected_type, of_selected_count, of_copy_path; ue_node_rclicked (right click, Menu key); ib_find_decoded (the search in the decoded values, & toggle)
xmltreeof_find_xpath (every node of an XPath, walked by of_search_next); of_get_layout, of_set_layout and ue_layout_changed (the folds, the selection, the line at the top); of_selected_kind (KIND_* constants), of_selected_name, of_selected_namespace, of_copy_path; ue_node_rclicked (right click, Menu key); ib_find_decoded (the search in the decoded values, & toggle)
jsonof_from_datastore and of_to_datastore (DataStore, DataWindow, DataWindowChild): a DataStore as an array of typed objects, and back; ISO 8601 dates (of_set_date, of_set_datetime, of_set_time, of_add_date, of_add_datetime, of_add_time, of_get_date, of_get_datetime, of_get_time); of_get_last_error and of_error_position (where a text is not JSON); of_escape_key
listbarue_item_invoked (a click on the entry, the one already selected included); ib_search, is_filter, ue_filter_changed (a search); of_from_datastore (DataStore, DataWindow, DataWindowChild), of_map and the ROLE_* constants (one row = one entry)
markdownviewis_base_path, ib_allow_html (a short list of inert HTML tags), ib_network_pictures, ib_remote_pictures, ib_tasks_editable and ue_task_toggled, ib_track_heading and ue_heading_visible, is_position, ii_zoom, of_selected_text, of_copy and Ctrl+Insert, the LINK_* constants; GitHub alerts, bare e-mail addresses and emoji
menubarof_load_menu(menu): the whole bar from the PowerBuilder menu of a window, read again at each opening, its Clicked scripts run; of_loaded_item; of_insert_item (an entry at a rank) and of_clear_items (empty a cascade and keep the entry); of_open, of_close, of_is_open
pdfviewerof_load_blob(blob) and of_load_blob(blob, string): a PDF held in a blob (read with SELECTBLOB), shown without a file, whatever its size; is_find (a text highlighted when the document opens); ib_navigation_pane (the reader's side panel); is_destination (open on a named destination of the PDF); ib_allow_search, ib_allow_rotate and ib_allow_fullscreen (the Search, Rotate and Full screen commands of the reader's toolbar)
pictureof_set_picture(blob): a picture held in memory (SelectBlob), like SetPicture of the native Picture; ib_clickable: the picture becomes a button for the keyboard (Tab, Enter, Space); the TIFF, WMF, EMF and RLE formats, converted on the fly; a name for screen readers that tells the badge and the failure
radialmenuof_show_over(dragobject ado_control {, boolean ab_keyboard}): the wheel centred on a control, its first branch lit when it comes from the keyboard; on the branch handle, is_image (icon changed in place), is_tone (TONE_* constants of u_pbt_radialmenu) and is_group (radio group)
restclientof_url and of_url_encode (an encoded URL query); of_post_form and of_post_form_async (an HTML form); of_oauth_client_credentials (an OAuth2 token renewed by itself); of_retrieve (DataStore, DataWindow, DataWindowChild: a JSON array as rows); the headers of one request (of_request and of_request_async, fourth argument as_headers); is_last_request; ib_check_revocation
statusbarib_spring (and a width of -1 in of_add_panel, of_insert_panel): a panel that takes the free room; of_dock_bottom (the bar at the bottom of its window); is_help and is_help_panel (the MicroHelp of a PowerBuilder frame); ib_announce (screen readers); the tooltip of an elided text
tilesboxof_move_tile(as_keys, as_to_key, al_position): a tile sent by the code into another group, with its colours, badge and faces; Escape cancels a drag, the panel scrolls when the pointer nears its edge; a screen reader hears the badge and the band of a tile; an SVG icon stays sharp on a large tile; the header of a group lights up under the pointer; the "less motion" setting of Windows is honoured
statictextib_mnemonic (the & of a PowerBuilder label), ii_max_lines (at most N lines, "…"), il_max_log_lines and of_clear (a bounded log, emptied), ii_max_width (ceiling of ib_auto_width), ib_veto_links and ue_hyperlink_opening (deciding whether a link opens); a log is announced line by line to screen readers; disabled, the zones of the markup leave the Tab order
xmlof_get_number, of_get_decimal, of_get_longlong, of_get_boolean, of_get_date, of_get_datetime: the value at the XPath checked against its XML Schema type and read the same way on every machine (NULL and of_get_last_error() when it is not of that type)
xmldecimal, date, datetime, boolean overloads of of_leaf, of_element_attr and of_set_value: written with a point and in ISO 8601 whatever the machine

12.7 buttonbar: key, label, then icon; the "&" and the chord #

The button bar spoke differently from the rest of the library: the icon before the label, the position as the second argument, and an is_shortcut that meant "Alt letter" where it means "chord" everywhere else — is_shortcut = "Ctrl+S" armed Alt+C. 5.0 aligns it with button, the toolbar and the PowerBuilder CommandButton.

What4.05.0
Add a buttonuo.of_add_button("save", "img\save.png", "Save")uo.of_add_button("save", "&Save", "img\save.png")
A text-only buttonuo.of_add_button("ok", "", "OK")uo.of_add_button("ok", "OK")
Insert a buttonuo.of_insert_button("mid", 2, "", "Mid")uo.of_insert_button("mid", "Mid", "", 2)
The Alt letter of a buttonis_shortcut ← "S" (Alt+S)the label "&Save", or uo.of_button("save").is_mnemonic = "S"
A chord on a buttonuo.of_register_shortcut("Ctrl+S", "save")the same, or uo.of_button("save").is_shortcut = "Ctrl+S" — shown in the tooltip
A "&" in a labelshown as ismarks the Alt letter; && for a written "&"
The badgeuo.of_button("inbox").il_badge = 3uo.of_button("inbox").is_badge = "3" (a text: "New", "!"); il_badge is still accepted
The focused button, without is_defaultpainted with a full accentits focus ring only
// 4.0 : the icon before the label
uo_bar.of_add_button(/*key*/ "save", /*image_file*/ "img\save.png", /*text*/ "Save")

// The Alt letter went to is_shortcut (the letter S alone), the chord to of_register_shortcut
uo_bar.of_register_shortcut(/*chord*/ "Ctrl+S", /*key*/ "save")
// 5.0 : key, label, icon - the "&" of the label gives Alt+S
uo_bar.of_add_button(/*key*/ "save", /*text*/ "&Save", /*image*/ "img\save.png")

// The chord is a property of the button, shown in its tooltip
uo_bar.of_button(/*key*/ "save").is_shortcut = "Ctrl+S"

The recipe: compile; a call of of_insert_button is reported (the position goes last). A three-argument of_add_button still compiles: swap the last two (the label, then the icon) — a button whose label is a file path shows you the ones left. Replace every one-letter is_shortcut with a "&" in the label, and double every "&" that must be shown (R&&D).

12.8 crosstab: the format of the values through is_format #

The crosstab wrote the numbers of a measure through a function with four or five arguments (decimals, thousands separator, symbol, symbol before), which held for every value of a field: the same field twice in Values — the amount, and its share of the total — could not have two formats. 5.0 puts it under the language of the charts and the gauges: a PowerBuilder display format in is_format, on the handle of the field (of_field) for all its values, or on the handle of one value (of_value(position), new) for it alone. Empty, a value takes the Format of the DataWindow column. No old name survives.

What4.05.0
The format of every value of a fielduo.of_set_value_format("amount", 2, "locale", "$", true)uo.of_field("amount").is_format = "$#,##0.00"
A symbol after the numberuo.of_set_value_format("amount", 0, "", " EUR")uo.of_field("amount").is_format = '#,##0" EUR"'
The format of one value (the same field twice)—uo.of_value(2).is_format = "#,##0.00"
Negatives in redthe chip menu onlyuo.of_value(1).ib_negative_red = true
Back to the default formatuo.of_clear_value_format("amount")uo.of_field("amount").is_format = "" (the Format of the DataWindow column)
// 4.0 : decimals, thousands, symbol and its side as arguments - for every value of the field
uo_cross.of_set_value_format(/*field*/ "amount", /*decimals*/ 2, /*thousands*/ "locale", /*suffix*/ "$", /*symbol_before*/ true)
// 5.0 : a display format, written as in a DataWindow - for the field, then for its second value alone
uo_cross.of_field(/*field*/ "amount").is_format = "$#,##0.00"
uo_cross.of_value(/*position*/ 2).is_format = "#,##0"

The recipe: compile; every of_set_value_format and of_clear_value_format is reported. Write the format as in a DataWindow: ai_decimals gives the number of 0 after the point, a thousands separator gives the grouping , ("none": none), the symbol is written before or after (in quotes when it holds digits or spaces). The format of one value alone goes into of_value(<position>).is_format.

12.9 listbar: the right click carries its point, a layout is announced #

The side bar joins the library on three points: the right click of an entry gives its screen point like the one of the trees, the grids and the kanban; an order of the code that changes the layout announces it like a gesture; a greyed entry no longer becomes the selection. It also gains an event for the click on the entry already selected, a search and the building from a DataStore (12.6).

What4.05.0
ue_item_rclicked(string as_keys)(string as_keys, long al_x, long al_y): the point in screen pixels; the Menu key and Shift+F10 raise it too
of_set_layout that changes the layoutno eventone ue_layout_changed (never ue_section_toggled)
of_move_item / of_move_section to the rank already heldue_layout_changednothing: nothing moved
of_select_item of a greyed entry0, it became the selection-5, without asking ue_selection_changing; greying the entry already selected keeps it
ib_auto_width read while the bar is in the railtruewhat the application set
of_item of an address of one level ("nav")reached the sectiona handle that names nothing; a section is reached by of_section
The same letter typed twicea prefix dd, often matching nothingthe next line that starts with it; a Space in the middle of a prefix belongs to it
A greyed entry under the pointerno tooltipits tooltip shows; the click still does nothing
// 4.0 : PointerX() of the userobject - the menu opened too high under a ribbon
m_entry.PopMenu(PointerX(), PointerY())
// 5.0 : the pointer of the WINDOW for a PowerBuilder menu (al_x, al_y serve a menu of the library)
m_entry.PopMenu(parent.PointerX(), parent.PointerY())

The recipe: nothing refuses to compile — a script of ue_item_rclicked keeps as_keys. Open your menu at the pointer of the window (parent.PointerX()), or hand al_x, al_y to of_show of a contextmenu. Set the initial selection before switching ib_veto_selection on, and make sure your ue_layout_changed accepts the call of_set_layout now makes to it.

12.10 scheduler: the kind of a change and the values it had #

The calendar joins the Gantt chart: the question asked before a gesture says whether it is a move or a resize, and the events that follow give the values the appointment had — a log, an undo or a confirmation no longer keep their own copy of every appointment. A selection your code takes away is announced, and four calls now refuse what they accepted in silence.

What4.05.0
ue_appointment_changing(string as_key, string as_start, string as_end, string as_resource)(string as_key, string as_kind, string as_start, string as_end, string as_resource): as_kind is CHANGE_MOVE or CHANGE_RESIZE
ue_appointment_moved(string as_key, string as_start, string as_end, string as_resource)(string as_key, string as_start, string as_end, string as_resource, string as_old_start, string as_old_end, string as_old_resource)
ue_appointment_resized(string as_key, string as_start, string as_end)(string as_key, string as_start, string as_end, string as_old_start, string as_old_end)
Your code removes, empties or reloads the selected appointmentno eventue_selection_changed(""); of_reset stays silent
of_add_appointment whose end comes before its start0, the end became start + 30 min-5, of_get_last_error says why
of_scroll_to_time("abc")0, nothing scrolled-5
of_set_field on the column playing ROLE_KEY0, two appointments of one key-5: a key changes by reloading
of_show_appointment of an appointment hidden, filtered out or on a hidden resource0, the view left for a day where nothing could be seen-5, nothing moves
is_now set after a navigation of the userbrought the view back to its daythe view stays where the user went
of_clear_appointmentskept the columns of the DataStore for of_mapforgets the DataStore: of_map accepts the columns of the next one
// 5.0 : ue_appointment_changing event of uo_sched : (string as_key, string as_kind, string as_start, string as_end, string as_resource) returns boolean
// A resize keeps the day : only a move is checked
if as_kind = u_pbt_scheduler.CHANGE_RESIZE then return true

// Nothing on a Saturday or a Sunday : returning false puts the appointment back
if DayNumber(Date(Left(as_start, 10))) = 1 or DayNumber(Date(Left(as_start, 10))) = 7 then return false
return true

The recipe: nothing refuses to compile — a script of ue_appointment_changing, ue_appointment_moved or ue_appointment_resized keeps its arguments, the new ones are added. If your ue_selection_changed enables buttons, it now receives "" when the selected appointment leaves; read again the return codes of of_add_appointment, of_scroll_to_time, of_set_field and of_show_appointment, which may now return -5. To save the gestures without code, see ib_write_back.

12.11 shellexplorer: the error says its reason #

The shell explorer now gives, in ue_error as in ue_path_not_found, a reason your code can test — a REASON_* constant of u_pbt_shellexplorer, the same in every language of Windows. It no longer raises ue_selected for the folder already selected, and announces with ue_collapsed a branch it closes by itself. It also gains the right click on a folder (ue_node_rclicked) and the address of the root.

What4.05.0
ue_error(string as_message)(string as_path, string as_reason, string as_message): the path ("" for the Desktop), a REASON_* constant, the text of the shell
as_reason of ue_path_not_foundan English sentence (not found, outside the root, not a branch…)a REASON_* constant (not_found, outside_root, not_a_branch…); not_shown for a path that exists but that the tree does not show
Selecting the folder already selected (a click, Home on the first row)ue_selectednothing
A branch the tree closes by itself (came back empty, refused by the shell)no eventue_collapsed
ib_show_files, ib_show_hidden, is_file_filter, is_root written with their valuethe tree is read againnothing is read again; is_file_filter set without the files waits for them
of_collapse of a path drawn twiceevery row, one ue_collapsed eachthe row of_select reaches, one ue_collapsed
of_count(""), of_keys_at("", i)the rows shown, as of_count()the first level (the root), as of_count(is_root)
// 5.0 : ue_error event of uo_tree : (string as_path, string as_reason, string as_message)
// Test the reason, never the text of the shell
if as_reason = u_pbt_shellexplorer.REASON_TIMEOUT then
    st_status.text = "The network folder " + as_path + " does not answer"
else
    st_status.text = as_message
end if

The recipe: nothing refuses to compile — a script of ue_error keeps as_message, the new arguments are added. A test on the TEXT of as_reason in ue_path_not_found ("not found", "outside the root") is written again with a REASON_* constant; an application that reloaded a pane at every ue_selected now does it once per change.

12.12 tilesbox: the right click carries its point, an order of the code is announced, the layout leaves the rights to the application #

The tiles box joins the library: its right click gives the screen point like the one of the trees, the grids and the kanban; an order of the code that moves a tile, folds a group or changes a size raises the same events as a gesture; the layout no longer carries the visibility, which stays the application's business. It also gains moving a tile into another group from the code (12.6).

What4.05.0
ue_tile_context(string as_keys)ue_tile_rclicked (string as_keys, long al_x, long al_y): the point in screen pixels; the Menu key and Shift+F10 raise it too, at the bottom-left corner of the tile
of_move_tile, of_insert_tileinteger ai_indexlong al_position; an overload of_move_tile(as_keys, as_to_key, al_position) sends the tile into another group
of_move_tile to another placenothingue_tile_moved, ue_layout_changed
ib_collapsed of a group set by the codeue_group_toggledue_group_toggled, ue_layout_changed
is_size set by the codenothingue_layout_changed (never ue_tile_resized, which says the user chose it)
is_size of an unknown size ("huge")the tile became mediumrefused: nothing is written, of_get_last_error says why; of_add_tile / of_insert_tile return -5
The layout (of_get_layout, ue_layout_changed)carried the visibility of the groups and tilesno longer carries it: of_set_layout never shows again what your code hid; a 4.0 layout is read without it
of_set_layout that changes the layoutno eventone ue_layout_changed; -5 on a JSON that is not a layout ({})
of_tile / of_group of an address that names nothingone handle per call, keptthe inert handle, the same for them all: it writes nothing and reads empty
// 4.0 : the right click of a tile
// ue_tile_context event of uo_tiles : (string as_keys)
// 5.0 : the same script, under the new name, with the screen point
// ue_tile_rclicked event of uo_tiles : (string as_keys, long al_x, long al_y)

The recipe: compile; your script of ue_tile_context stays on an event that no longer exists — move it to ue_tile_rclicked, which keeps as_keys. If your ue_layout_changed saves the layout, it now also sees what your code changes; a ue_tile_moved that must only react to the user ignores the moves your code has just made. If you kept the visibility in the layout, set it from the code at opening (ib_visible), according to the rights.

12.13 tab: the right click carries its point, an applied layout is announced #

The tab joins the library: the right click of a tab, built-in menu off, gives its screen point like the one of the trees, the grids and the kanban, and of_set_layout that changes the layout announces it like a gesture. A drag given back to its place no longer announces anything. It also gains pages created on demand (ue_page_needed, of_supply_page), the double click (ue_tab_double_clicked), ib_cycle_keys, is_close_mode, ii_strip_width and, on a page, ib_modified and is_badge — see the page of the tab.

What4.05.0
ue_tab_rclicked(string as_key)(string as_key, long al_x, long al_y): the point in screen pixels; the Menu key and Shift+F10 raise it too, at the bottom-left corner of the tab
of_set_layout that changes the layoutno eventue_layout_changed, once
a drag given back to its place, of_move_page to its own placeue_tab_reordered and ue_layout_changednothing: the order did not change
several moves under of_set_redraw(false)one ue_layout_changed per movea single one, at the resume
Shift+F10 on a tab, built-in menuthe menu opened under the mouseunder the tab
vertical strip and long titlethe strip took the width of the title40 % of the component at most, ellipsis; ii_strip_width fixes it
il_accent of a pagethe focus ring onlyalso underlines the active tab
is_shortcut on the handle of a key no page hasregistered: the key was taken for nothingnothing is registered, of_get_last_error says why
of_insert_page whose move failsa negative code, the page stayeda negative code, the page is taken out again
// 4.0 : the right click of a tab, built-in menu off
// ue_tab_rclicked event of uo_tabs : (string as_key)
// 5.0 : the same script, with the screen point
// ue_tab_rclicked event of uo_tabs : (string as_key, long al_x, long al_y)

The recipe: nothing refuses to compile — a script of ue_tab_rclicked keeps as_key. Open your menu at the pointer of the window (parent.PointerX()), or hand al_x, al_y to of_show of a contextmenu. Make sure your ue_layout_changed accepts the call of_set_layout now makes to it.

12.14 soundplayer: the number of a sound, a refusal returned at once #

The sound player changes three things your code can see. Its events carry the number of the sound: ue_started, ue_ended and ue_failed receive a last argument, al_sound — the number of_play_over and of_enqueue now return (they returned 0), and that the new of_stop_sound takes. A source refused at once is a code: of_play, of_play_over, of_crossfade and of_preload return -5, the reason in of_get_last_error(), for an empty source, an http:// address, a malformed file:// address or a format refused by its name — and no longer raise ue_failed; the sound playing goes on. In the queue (of_enqueue), the refusal still comes through ue_failed, at its turn. Other -5: of_pause and of_resume with nothing to suspend or resume, of_beep and of_beep_sync at 0 Hz or 0 ms, of_meter out of 1 to 64 bars.

// Local variables
string ls_url
long ll_rc

// The address of the sound, typed by the user
ls_url = sle_url.text

// 4.0 : of_play returned 0, and an http:// address came back later through ue_failed
// 5.0 : the refusal is a code, at once ; of_get_last_error() gives the reason
ll_rc = inv_sound.of_play(/*source*/ ls_url)
if ll_rc = -5 then
	MessageBox("Sound", inv_sound.of_get_last_error())
end if

What changes without asking anything of your code: of_stop now dies out over il_fade_ms, as the documentation promised (ue_stopped still comes at once); when il_timeout_ms runs out, only the sound of the synchronous call is cut — the background, the overlays and the queue go on; of_crossfade to a refused source keeps the track playing; of_level is 0 and of_spectrum returns no bar, meter off; of_equalizer(ab_on, ai_gains[]) sets back to 0 a band the array does not reach; of_clear_queue also forgets the sounds the queue already played; the messages of ue_failed follow the display language (as_reason stays the word to test). The player also gains the queue that moves (of_next, of_previous, of_queue_index, ue_source_changed, ib_queue_repeat), the loop without a gap (ib_gapless_loop, REASON_TOO_LONG), the segment (of_play_range), the mute (ib_muted) and the buffering (ue_buffering, of_is_buffering) — see the page of the sound player.

The recipe: nothing refuses to compile — a script of ue_started, ue_ended or ue_failed keeps its arguments, al_sound is added. Read again the return-code tests of of_play_over and of_enqueue (a = 0 becomes > 0), and the code that waited for ue_failed for an http:// address or an empty source: it now tests the -5 of the call.

12.15 toaster: the reason of a closing, a toast closed by the code always says so #

The toaster says why a toast closed: ue_toast_dismissed receives a last argument, as_reason — REASON_TIMEOUT, REASON_USER (its cross), REASON_CODE (of_close, of_close_all) or REASON_OWNER_CLOSED (its window closed). And every toast closed by the code announces it, even closed right after of_show, before it was drawn, or while it waited for room: an application that waited for ue_toast_dismissed to free its state no longer depends on a race.

What4.05.0
ue_toast_dismissed(long al_id, string as_key)(long al_id, string as_key, string as_reason), constants REASON_*
of_close of a toast not drawn yet, or waiting for roomnothing was raisedue_toast_dismissed, REASON_CODE
of_close of a toast of another toasterclosed it, the announce went to the other one-5, nothing is closed, of_get_last_error says why
the window of ipo_owner closesits toasts went away without a wordue_toast_dismissed, REASON_OWNER_CLOSED
a toaster destroyed, toasts on screenthey stayed, silentthe persistent ones and those with buttons close with it; the others finish on their own
of_show before the display engine is ready-6: "runtime missing"-4: try again; of_get_last_error says why
corner of a toast anchored to the windowthe whole window: the toast covered the title bar and its buttonsthe client area (the frame's, in MDI)
a very long titlepushed the cross and the buttons out of the windowcapped, it scrolls
// 4.0
// ue_toast_dismissed event of inv_toaster : (long al_id, string as_key)
// 5.0 : the same script, with the reason
// ue_toast_dismissed event of inv_toaster : (long al_id, string as_key, string as_reason)

The recipe: nothing refuses to compile — a script of ue_toast_dismissed keeps al_id and as_key, as_reason is added. Read again the code that assumed a toast closed at once by of_close would say nothing: it now announces it. Toasts stay tied to the toaster that showed them: an of_close on the id of another toaster returns -5. The toaster also gains of_close_all (close all its toasts) and of_get_last_error — see the page of the toaster.

12.16 video: a refusal returned at once, a film and its subtitles in one call, the same film resumed #

The video player changes five things your code can see. A refusal is returned at once, as in the sound player (12.14): of_play(), of_play(source) and of_play_range return -5, the reason in of_get_last_error(), for an empty source, an http:// address or a format refused by its name (avi, wmv, flv) — and no longer raise ue_failed; the film playing goes on. The is_source property keeps its ue_failed: a property has no return code. The same film is not reloaded: of_play(source) or is_source on the film already loaded resumes it where it is (ue_resumed) instead of starting it over; of_seek(0) starts it over. A seek stays in the segment of of_play_range, the user's as well as of_seek: Home goes to the start of the segment, a click past its end to its end — before, Home left the extract and a click past it stopped the film. A playlist entry that cannot play raises ue_source_changed first, then one ue_failed — it came before, and twice. of_stop becomes a function: it returned nothing (a subroutine), it returns 0, or -2 when the component is not created — like of_stop of the web browser.

// Local variables
string ls_path
long ll_rc

// The film chosen by the user
ls_path = sle_film.text

// 4.0 : of_play returned 0, and an http:// address or an .avi came back later through ue_failed
// 5.0 : the refusal is a code, at once ; the reason is in of_get_last_error
ll_rc = uo_video.of_play(/*source*/ ls_path)
if ll_rc = -5 then
	MessageBox("Video", uo_video.of_get_last_error())
end if

What changes without asking anything of your code: a marker reached by a seek WHILE PAUSED no longer raises ue_marker_reached (only ue_seeked); Space and the Play button of a player with no film no longer do anything (they raised ue_failed(REASON_NO_SOURCE)); the subtitle language the user chose follows to the next film of the playlist; an http:// poster is refused and is_poster reads back empty; a refused is_subtitles reads back empty; a subtitle file of the workstation that cannot be found raises ue_subtitles_failed(REASON_NOT_FOUND); the speed menu works at the keyboard and its arrows no longer change the volume; in full screen the bar shows at the keyboard; the remembered position (ib_remember_position) no longer depends on how the path is written, and only the last 200 films are kept (a position of 4.0 is read once more). The player gains of_play(source, subtitles) (the film and ITS subtitles: set before a second film, they went with the first one), ib_forward_seek, of_watched_ms, of_watched_percent, ue_watched_completely and ib_skip_failed — see the page of the video player.

The recipe: nothing refuses to compile. Read again the code that waited for ue_failed after of_play for an http:// address, an empty source or an .avi: it now tests the -5 of the call. Read again too a "Play" button that relied on of_play(source) to start over: add of_seek(0).

12.17 webbrowser: a gesture of the user is asked about, a page of of_show_html has no address #

With ib_veto_navigation = true, ue_navigating is now also asked for a gesture of the user: an address typed in the bar, Open link of the context menu, a new window opened by a click. In 4.0 these three paths did not ask. Only an address set by your code is never asked about, and nor is a redirection of the server: for a list of servers that also holds for redirections, set the new property is_allowed_hosts.

What4.05.0
ue_navigating under the veto: address typed, Open link, new windowthe page opened without a questionthe question is asked; false keeps the page
is_address, the bar, ue_load_completed after of_show_htmlthe whole page, encoded (data:text/html;charset=utf-8,…, up to 2 MB)""
is_title of a page without <title>its address""
of_go_back, of_go_forward, of_stopno return valuelong: 0 once asked, -2 component not created
ib_private changed after a pageis_address, is_title, the bar and the arrows kept the page beforeeverything reads empty: the view is new
Enter on an empty address barthe page went blanknothing
A page of the site is loading, address bar shownReload stays ReloadReload becomes Stop, and comes back once the page is done

The recipe: nothing refuses to compile, an ignored long compiles. A script of ue_navigating written for the links of the site now also sees the addresses typed by the user: if it decides on the address, let it compare its host, as the example of the component page does — or hand the list to is_allowed_hosts. The code that read as_url of ue_load_completed, or is_address, after of_show_html receives an empty string.

12.18 toolbar: the right click carries its point, an order of the code is announced #

The toolbar joins the library: the right click of a tool gives its screen point, like that of the trees, the grids and the tab, and moving a bar by ii_band / ii_index raises ue_bar_reordered like the gesture. Two adds refuse what they accepted silently, and a shortcut set where nothing lives is no longer registered. It also gains is_text on a bar, a name for every tool and field read by a screen reader, and a keyboard that crosses the fields — see the toolbar page.

What4.05.0
ue_item_rclicked(string as_keys)(string as_keys, long al_x, long al_y): the point in screen pixels; the Menu key and Shift+F10 raise it too, at the bottom-left corner of the tool, and so does the right click of a field
ii_band / ii_index moving a barue_layout_changedue_bar_reordered, ue_layout_changed
of_add_datepicker with a date that is not yyyy-mm-dd ("31/12/2026")0, the date shown as it was-5, nothing is added
of_add_menu_separator on an entry that holds no sub-entry0: the entry turned grey and could no longer be chosen-5
is_shortcut or of_register_shortcut on an address where nothing lives, an entry holding a cascade or a choice of a listregistered: the key was taken in the whole windownothing registered; of_register_shortcut returns -5, of_get_last_error says why
Ctrl+A, Ctrl+C, Ctrl+V, Ctrl+X, Ctrl+Z, Ctrl+Y in a field of the barthe tool holding the chord firedthe field edits its text
is_text of a date pickerkept and read back, never shownignored, reads ""
// 4.0 : the right click of a tool
// ue_item_rclicked event of uo_toolbar : (string as_keys)
// 5.0 : the same script, with the screen point
// ue_item_rclicked event of uo_toolbar : (string as_keys, long al_x, long al_y)

The recipe: nothing refuses to compile — a script of ue_item_rclicked keeps as_keys. Open your menu at the point al_x, al_y (hand it to of_show of a contextmenu). Check that a script of ue_bar_reordered also accepts the moves your code makes, test the return code of of_add_datepicker when the date comes from a regional field, and set is_shortcut after the add of the tool or the entry.

12.19 The right click of an item carries its point: buttonbar, breadcrumb, chartcartesian, statusbar #

One rule for every right click on an item of the library: the event receives the key (or the address) of the item, then al_x, al_y, the point where to open a menu, in screen pixels — the pointer, or, from the keyboard (Menu key, Shift+F10), the bottom-left corner of the item (bottom-right in a right-to-left reading; the middle of a shape that is no rectangle: a point of a chart). A contextmenu of the library opens there as they are: uo_menu.of_show(al_x, al_y). Three events that did not carry it receive it; the status bar multiplied its own by the scale of the display, and a menu opened at that point landed far from the pointer on a display at 125 % or 150 %.

What4.05.0
buttonbar · ue_button_rclicked(string as_key)(string as_key, long al_x, long al_y)
breadcrumb · ue_item_rclicked(string as_keys)(string as_keys, long al_x, long al_y)
chartcartesian · ue_point_rclicked(string as_key, long al_index, double ad_value)(string as_key, long al_index, double ad_value, long al_x, long al_y)
statusbar · al_x, al_y of ue_panel_rclickedmultiplied by the scale of the displaythe point as the page reads it, like every right click
// 5.0 : the menu of a button, opened where the user right-clicked it
// ue_button_rclicked event of uo_buttons : (string as_key, long al_x, long al_y)
is_menu_button = as_key
uo_menu.of_show(/*x*/ al_x, /*y*/ al_y)

The recipe: nothing refuses to compile — a script of these events keeps its arguments. Open your menu at the point al_x, al_y (hand it to of_show of a contextmenu); a PowerBuilder menu keeps PopMenu(PointerX(), PointerY()) of your window. A script that corrected the scale of the coordinates of ue_panel_rclicked itself must no longer do it.

12.20 The foundation: a component's error is its own, every verb returns a code #

Five changes touch the whole library, or a whole family of components. Only one refuses to compile: is_last_error of a non-visual component, now of_get_last_error().

What4.05.0
of_get_last_error() of a visual componentthe last message of the DLL, one for the whole process — often another component'swhat happened to this component: a name refused, or a call of this component to the DLL, whose reason is read at the moment it failed; empty otherwise
The reason a non-visual component failed (crypto, restclient, soundplayer, speechout, xml, u_pbt_regex, u_pbt_zip)inv.is_last_errorinv.of_get_last_error()
of_stop, of_close, of_reset of the non-visual components (commandpalette, crypto, messagebox, restclient, soundplayer, speechout, toaster, xml)no return valuea long, 0 once done — like the visual components
of_set_property("tooltip", …) and super_tooltip_* on a component without a tooltip (webbrowser, pdfviewer, radialmenu, progressbar)set a tooltip the documentation says does not exist-5, and of_get_last_error() says why
The shortcut of a PowerBuilder menu taken over (of_load_menu of menubar and commandpalette)Ctrl++, PageUp, Insert (menubar); nothing past F12 (palette)one writing, the contextmenu's: Ctrl+Plus, PgUp, Ins, F13 to F24, Num 0 to Num 9, Num +
// Local variables
string ls_why

// 4.0 : ls_why = inv_crypto.is_last_error
// 5.0 : the reason of a failure, by the same method as every component
ls_why = inv_crypto.of_get_last_error()

The recipe: the compiler shows each .is_last_error to replace with .of_get_last_error(). A call to of_stop, of_close or of_reset written as a statement still compiles. A script that read of_get_last_error() of a component to learn the failure of another call (an export of the DLL called directly, another component) now reads that component's own reason, or nothing: ask the one that failed.

Added, nothing to rework: is_accessible_name and is_accessible_description on every visual component — the name and the description a screen reader says (3.4); of_from_datastore of a DataWindow or a DataWindowChild on crosstab and datagrid, as on the other data-bound components; the full form of of_insert_command (commandpalette), which takes the hint, the shortcut and the keywords as of_add_command does, with a long position.


← Migrating from 3.0 to 4.0 · Contents · Release notes →