System Settings (Maintain Table Screen): Difference between revisions

From OpenPetra Wiki
Jump to navigation Jump to search
(Replaced content with "Deprecated: this only applied to the winforms client")
Tag: Replaced
 
Line 1: Line 1:
== Overview ==
Deprecated: this only applied to the winforms client
The System Settings screen is an example of a relatively simple [[Creating some simple Maintain Table Screens | Maintain Table Screen]] but it differs from all the others in one important respect.  Some of the controls on the screen are dynamically created as they are needed.  This means there are some unusual programming features related to this screen but more importantly the control definitions for these dynamic controls are in the ''database'' and not in a YAML file.
 
The purpose of this page is to provide documentation for how to define and use these dynamically created controls.  The System Settings screen will be used as an example.  The screen looks like this.
 
[[File:SystemSettings1.jpg]]
 
The screen consists of a grid which displays filtered rows depending on the ComboBox selection at the top.  The database table that backs this screen is s_system_defaults which is a non-cached table.  The group box beneath the grid is all set up in the YAML file.  The area beneath the group box is where controls are created dynamically depending on the content of the database.
 
== Design Goal ==
The goal for the handling of system settings was to create a workflow where a new system setting could be added that would allow us to tailor the behaviour of Open Petra specifically for a particular country without the need to add code to the GUI where system settings are managed.  Of course there would presumably be code changes to '''make use''' of the setting but there would be no need to add new controls (or even a new tab) to the System Settings screen itself.  The screen would provide a client GUI interface to the setting automatically by reading information from the database.
 
== Database Design ==
 
=== The s_system_defaults Table ===
This table has the following columns.  If you wish to add a new system setting to Open Petra you will do so by following these instructions.
* '''s_default_code_c''':  This is the code for the setting and is the Primary Key.  The value will likely be something technical and will only occur in C# code.  It will be a code that looks good to a programmer and will only be seen by Open Petra programmers, who will almost always assign the value to a string constant.
* '''s_default_code_local_c''':  You should enter here a more friendly, but short, definition of what the setting is for.  This can be in English or any other language.  This will be how the GUI displays the code that is being set.
* '''s_default_code_intl_c''': If s_default_code_local_c is in English you can leave this column as NULL.  However if, for example, you wrote the local column in Spanish, you should write the English equivalent in this column.  It is helpful if the entire text in this field is written inside braces ().  The reason for the existence of this field is that it will be the only way that support staff in the UK will be able to understand what a screen-shot is about when the whole text on the screen is in a 'foreign' language!  The text that you use in this column is displayed at the top right corner of the information box in the screenshot shown above.
* '''s_default_description_c''':  This column allows for a lengthy description of the purpose of the setting and the result of choosing one particular value rather than another.  This too can be in any language.  Its purpose is to help the client to decide what value to assign to the setting.
* '''s_category_c''':  An individual setting can be assigned to a category, for example Partner or Finance.  This can be in any language.  The value you choose is not referenced as a foreign key anywhere.  The screen will display all the ''distinct'' categories in the Combo Box above the grid and will filter the displayed rows based on the Combo Box selection.  Note that if this column value is NULL the system setting will not be displayed.
* '''s_default_value_c''':  This contains the current value for the setting as a text string.  When you create the row in the table this will hold the initial value for the setting.  Thereafter, as a system administrator uses the GUI to modify the value it will contain the current value.  The design allows for a setting to contain more than one value as a comma-separated list.  So, for example, the value might be 'no, 4', which might represent a Boolean choice and an integer number.
* '''s_read_only_l''':  This Boolean flag controls whether the setting is read-only when displayed.
 
=== The s_system_defaults_gui Table ===
==== Table Content ====
If you want a row in the s_system_defaults table to appear on the System Settings screen you must include one or more rows for that setting in this table.
 
If you want a system setting to be not client-editable you do not make an entry for that setting in this table.
 
This table has the following columns. 
* '''s_default_code_c''':  This column contains the same case-sensitive value that is the Primary Key in the s_system_defaults table.
* '''s_control_id_i''':  If this setting has a simple value that requires only one control to modify it, this column can simply contain the number 0.  However, if the s_default_value_c field in s_system_defaults is a comma-separated list of values you will need to create a matching control array.  Each control will have a row in this table that shares the same s_default_code_c value but has a different integer in this column.  These values will typically be 0, 1, 2 and so on but they could be 10,20,30 because it is the order of the numbering rather than the actual numbers that defines the order in which the controls are displayed on screen.
* '''s_control_label_c''':  This field contains the text for the label for the control.  It can be in local language.
* '''s_control_type_c''':  This field defines the type of control that is to be used.  Only the first three characters of the string you enter here have a significance.  Supported values are 'txt', 'cmb' and 'dtp', corresponding to TextBox, ComboBox and DatePicker.  See s_control_attributes_c below for an explanation of how the type of control can be influenced by including attributes.
* '''s_control_optional_values_c''':  This column is only relevant for certain types of ComboBox.  You define here the strings that will be used to populate the ComboBox items as a comma-separated list.  The column can be NULL if no values need to be supplied.
* '''s_control_attributes_c''':  This column contains a list of attribute name/value pairs that modify the appearance or content of the control.  They are described in the section below.
 
==== Control Attributes ====
The s_control_attributes_c column contains an optional comma-separated list of attributes that alter the look or behaviour of the control.  Here is a list of supported attributes.
* '''LabelWidth=n'''  By default the label takes up half the current width of the screen (leaving the right hand half available for the active control).  You can modify this layout by specifying this attribute.  It really only makes sense to use this for a short label that needs a wide active control.  The control will be located close to the right hand end of the label.
* '''Width=n'''  By default text boxes and combo boxes will stretch to fill the available space to the right of the label and will stretch as the screen is resized.  If you include a Width attribute the control will have the fixed size that you specify.
* '''Format=[option]''' Use the Format attribute to change the control behaviour as follows
** '''Format=Integer'''  Use this with a 'txt' control to display one of Open Petra's TtxtNumericTextBox controls.  This enforces that the client can only enter a valid integer number.
** '''Format=yes/no'''  This attribute applies specifically to combo boxes.  When this attribute is included the resulting default value from the user's choice is one of 'yes', 'no' or '?'.  The s_optional_values_c column contains the two options separated by a comma.  The first is the 'no' option and the second is the 'yes' option.  If the user can select neither option the result will be '?'.  The advantage of the yes/no format is that the combo box can display the two choices explicitly without having to think of a label that would be clear what both options do.  You can see how useful yes/no format can be by looking at the screenshot above.  The combo box option that is not shown in the screenshot states: 'Copy all the FAMILY addresses'.  This makes the choices clearer to the user.  You can still design a Boolean choice that does not use the yes/no format - but in that case you should set the s_optional_values_c column to False, True.  These text strings can be converted to a Boolean value by .NET.  You must not use localised language for Boolean values.
* '''AllowBlankValue=true'''  This attribute applies to controls of type 'cmb'.  It determines whether the user can leave the combo box with a blank entry which results in a '?' return value.
* '''List=[ListTable]'''  This attribute when applied to a control of type 'cmb' results in the creation of a TcmbAutoPopulated combo box containing data from the specified List Table.  So, for example List=CountryList will display a combo box containing all the countries supported by Open Petra.  If you include this attribute the s_optional_values_c column is ignored.
* '''Stretch=horizontally'''  This attribute can be applied to simple text boxes and simple combo boxes - but not to numeric text boxes, date pickers or auto-populated combo boxes.  It will ensure that if the screen is resized the control stretches accordingly.
 
==== Unsupported Control Types ====
These control types are not supported mainly because they take up more screen real estate or because the supported control types fulfil the functionality required.
* Check Boxes:  Both a two-state and tri-state check box has the same functionality as the two-option combo box.
* Radio Buttons: A yes/no combo box can be used in place of two radio buttons.  A standard combo box can be used in place of three or more radio buttons.
 
== Validation ==
When you add a new setting to the System Defaults table it is important that you test the screen to ensure that you have not made any mistakes with your control definitions in the database.
 
The dynamically created controls are all part of the Open Petra Validation Framework.  If the setting(s) for a particular System Default require validation this can be achieved in the usual way by including manual code in the screens ValidateDataDetailsManual() method.  The SystemSettingsSetup.MaualCode.cs file shows how this is done for one of the settings that uses a TextBox that should not contain empty text.  If the user does leave the control with empty text the usual tool-tip will be displayed and the user will not be able to leave the row without entering some text.
 
The same manual code file also shows how to call the Validate method on the 'smart' data table class referred to in the next section.  This checks that there were no errors in the definition of the controls in the s_system_defaults_gui table.  The System Settings screen already has this code, so when you add a new setting to the database it will already validate your data and check for mistakes.
 
Note that if you add a new system setting to Open Petra that requires validation then you will have to add code to the System Settings Setup manual code file.  Validation is '''not''' included in the data table design.  However at least validation does not affect the screen GUI design and the author has to write some C# code somewhere to make use of the new setting, so this is not a significant drawback in achieving our design goals.
 
== Program Architecture ==
The code to handle all aspects of creating and displaying the dynamically created controls and getting or setting their values is all handled in a 'smart' DataTable class called TGuiControlsDataTable in Ict.Petra.Client.CommonForms.  It was written this way so that we could use the class as a basis for including dynamic controls that are defined in a data table on other screens.
 
''If the situation arises in the future where we want to add another screen that uses dynamic controls'' we may want to make use of the following public methods:
* A '''constructor''' that requires you to pass in a reference to the data table containing the GUI definitions and the names of the six columns that the class requires.
* A '''ShowControls''' method with parameters that a screen would call from its ShowDetailsManual() method.  This single line is all that is necessary to display the controls for a given system code primary key.
* A '''GetCurrentValue''' method that returns a string that expresses the selected values.  This single call is all that is necessary to get the current value and would normally be called from the screen's GetDetailDataFromControlsManual() method.
* A '''Validate''' method, referred to in the previous section, that would be called from the screen's ValidateDataDetailsManual() method.
* A '''RemoveAllControls''' method that should be called if in ShowDetailsManual the passed in row is null.
 
The implementation of the System Defaults screen includes a feature whereby if the screen is opened while the SHIFT and ALT keys are both pressed all the other system defaults that would normally be hidden (because they do not have a category or they have no entries in the s_system_defaults_gui table) will be shown in a special 'category' named !SysAdmin!, which will normally be the first category in the list.  Of course they will have no controls to adjust the values and in any case all the settings in this category will be set to read-only.  This feature has been added because remote support staff who are trying to diagnose a 'problem' may be interested to know what the value is for a hidden setting.
 
==== Accessing the controls from the screen manual code file ====
If you need to access a control that was dynamically created you can do so by using the name of the control.  The control name will be cValue_0 (and cValue_1 and so on if a control array).

Latest revision as of 21:04, 11 Mayıs 2022

Deprecated: this only applied to the winforms client