Release 10.1A: OpenEdge Development:
Progress Dynamics Advanced Development

> ## Customizing the initializeObject procedure

> The next piece of code you need is a localization of the `initializeObject` procedure. This should first invoke the standard behavior with a `RUN` `SUPER` statement, as shown:

>      /* Run default behavior first. */
>         RUN SUPER.

> Next, it retrieves the `BrowsePopupActive` property value and creates the pop-up menu if the property hasn’t been set to `FALSE`, as shown:

>      {get BrowsePopupActive lPopupActive}.
>         IF lPopupActive THEN
>             RUN createBrowsePopupMenu ( INPUT TARGET-PROCEDURE ).

> .

> Note: The code excerpts here are not complete. All variable references, for example, are defined in the procedure or function where they are used. See the accompanying procedure file for the complete code.

> Before looking at the `createBrowsePopupMenu` procedure, the code must identify the key under which the profile values are stored. In order to allow you to customize a browser’s appearance differently in different container windows, the container’s name and the logical browser name are combined to form the key. If the container does not have a `LogicalObjectName` property value, then it is presumably a static container, so the procedure handle’s `FILE-NAME` is used instead, as shown:

>     /* Create the ProfileKey. */
>         {get ContainerSource hContainerSource}.
>         IF VALID-HANDLE( hContainerSource ) THEN
>             {get LogicalObjectName cContainerName hContainerSource} NO-ERROR.
>         ELSE
>             cContainerName = "".

>         IF ( cContainerName = "" ) AND VALID-HANDLE( hContainerSource ) THEN
>             cContainerName = hContainerSource:FILE-NAME.
>         cProfileKey = cContainerName + cBrowserName.

> ##### Using checkProfileDataExists and getProfileData

> Now you are ready to access the Profile Manager itself. Use a call to see whether profile data is defined for the profile code and key, as shown:

>     /* Try to restore column settings. Check the Profile Manager if the profile
>            data we're looking for actually exists... */
>         RUN checkProfileDataExists IN gshProfileManager (
>             INPUT "Browser",
>             INPUT "Columns",
>             INPUT cProfileKey,
>             INPUT YES,
>             INPUT NO,
>             OUTPUT lProfileExists ).

> The syntax for the `checkProfileDataExists` call is:

>     RUN checkProfileDataExists IN gshProfileManager
>         ( INPUT pcProfileTypeCode,
>           INPUT pcProfileCode,
>           INPUT pcProfileDataKey,
>           INPUT plCheckPermanentOnly,
>           INPUT plCheckCacheOnly,
>           OUTPUT plExists     ).

> These are its parameters:

> - `INPUT pcProfileTypeCode (CHARACTER)` — This is the code for the profile information type that you defined in the User Profile Code maintenance utility, browsers in the case of this example.

> - `INPUT pcProfileCode (CHARACTER)` — This is the subcode for the type that you also defined in the User Profile Code utility. You created profile codes for Columns and Sorting for the example.

> - `INPUT pcProfileDataKey (CHARACTER)` — This is whatever key you wish to define for storing and retrieving data for a particular code. In the case of the example, it’s the container name plus the browser name.

> - `INPUT plCheckPermanentOnly (LOGICAL)` — This flag tells the Profile Manager whether it should look only for settings marked as being permanent, as opposed to settings that are being saved for the session only. This is normally a settable user preference, although in our somewhat simplified example, browser settings are always saved as Permanent, as you will see later.

> - `INPUT pcCheckCacheOnly (LOGICAL)` — If this logical flag is set to `TRUE`, then only the currently cached data will be searched for the settings. If it’s `FALSE`, then the database table will also be checked if the setting is not found in the cache.

> - `OUTPUT plExists (LOGICAL)` — This returned value tells you whether the profile data you want is defined or not. In the example, there should be profile data for the key if this user had previously saved browser settings for this browser in this container, otherwise not.

> If there is already profile data for the combination of user, container, and browser, then the next call retrieves it, as shown:

>     IF lProfileExists THEN
>         DO:
>             ASSIGN rRowID = ?.
>             RUN getProfileData IN gshProfileManager (
>                 INPUT "Browser",
>                 INPUT "Columns",
>                 INPUT cProfileKey,
>                 INPUT NO,
>                 INPUT-OUTPUT rRowID,
>                 OUTPUT cProfileData ).

> The syntax for the `getProfileData` call is:

>     RUN getProfileData IN gshProfileManager
>         ( INPUT pcProfileTypeCode,
>           INPUT pcProfileCode,
>           INPUT pcProfileDataKey,
>           INPUT plNextRecordFlag,
>           INPUT-OUTPUT prRowID,
>           OUTPUT pcProfileData).

> The `getProfileData` procedure has these parameters:

> - `INPUT pcProfileTypeCode (CHARACTER)` — As in the previous function.

> - `INPUT pcProfileCode (CHARACTER)` — As in the previous function.

> - `INPUT pcProfileDataKey (CHARACTER)` — As in the previous function.

> - `INPUT plNextRecordFlag (LOGICAL)` — The `getProfileData` procedure can be used in some cases to walk through all profile records matching the combination of profile type code, profile code, and data key passed in. You can omit one or more of these parameters if you want to retrieve all records matching a partial set of keys. In such a case, `getProfileData` returns the profile data from one record at a time. In order to retrieve all the records, you must call `getProfileData` with the `NextRecordFlag` set to `NO` on the first call, and then continue to call it with the `NextRecordFlag` set to `YES` until an unknown value in the `RowID` parameter described next indicates that there are no more matching records. To retrieve a single data value, set this parameter to `NO`.

> - `INPUT-OUTPUT prRowID (ROWID)` — `getProfileData` always returns the `RowID` of the record that supplied the profile data, using this `INPUT-OUTPUT` parameter. If you are walking through a set of records, then you must pass the current `RowID` back in with each call after the first one, along with a `NextRecordFlag` of `YES`. If you only want to retrieve a single profile data value matching the three key values for `Type` `Code`, `Profile` `Code`, and Profile Key, then you must pass in the unknown value for this parameter; otherwise the Profile Manager will ignore the first three key value parameters and use the `RowID` as the basis for the request. If this parameter comes back as the unknown value, then there was no matching record (or no next record if `NextRecordFlag` was `YES`).

> - `OUTPUT pcProfileData (CHARACTER)` — You can store any meaningful character string you want as the data associated with a profile key. This parameter returns it to you.

> In its search for your profile data, `getProfileData` first looks in the client cache if it’s running client side. If the data is not found and this is not a cached profile type, it looks in the database. The procedure always checks for session data first, then permanent data. If a `RowID` is passed in, then this is used to find the record. The `RowID` is the `RowID` of the temp-table if this is a client-only profile type; otherwise it is the `RowID` of the database record.

> Profile types are either maintained completely using the client cache or always read from the database. When trying to get profile data, the procedure first fully caches the entire profile type if it is not already cached and this is a client-only profile type. Normally the full cache is built at application start-up, but profile types can be cached as used.

> The `initializeObject` procedure now has the profile data for this user, container, and browser, if it has been previously saved. If there is data, then the code manipulates the order and size of each browse column accordingly. Because this code is not pertinent to our study of the Profile Manager, just a couple of key lines are reproduced here, as shown:

>     …
>     hBrowse:MOVE-COLUMN( iColumnPosition, iLoop ).
>     hColumn:WIDTH-PIXELS = INTEGER( ENTRY( 2, cColumnEntry, CHR(4) )).
>     …

> Refer to the procedure file for the complete code example.

> Next, the code makes similar calls to `checkProfileDataExists` and `getProfileData` for data under the Sorting code. If a sort setting comes back, then it resets the query’s sort sequence accordingly, and reopens the SDO’s query. Note that the SDO is the `Data-Source` for the browser, so following that link identifies the procedure where the query must be reset and reopened. The `REFRESHABLE` attribute setting keeps the Browse from flashing as it is being manipulated, as shown:

>     hBrowse:REFRESHABLE = NO.
>     DYNAMIC-FUNCTION( "setQuerySort":U IN hDataSource, cProfileData ).
>     DYNAMIC-FUNCTION( "openQuery":U IN hDataSource ).
>     hBrowse:REFRESHABLE = YES.

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095