Working with Menu Modules
Creating Menu Modules*
Menu Components *
Creating, Saving, and Attaching Menu Modules *
Setting Menu Properties Using the Property Palette *
Creating Menu Toolbars *
Creating Pop-Up Menus *
Menu Item Type*
Managing Menu Modules*
Controlling the Menu Programmatically *
Customizing Menu Modules with Substitution Parameters *
Implementing Menu Security *
Controlling Menu Security Programmatically*
In this chapter, you will cover the following facets of working with menu modules:
Menus are a fact of life in modern application development. Form Builder has features that make it extremely easy to create custom menus for your applications. In this chapter, you will learn how to create custom menus and toolbars, including context-sensitive pop-up menus. In addition, you will learn to control menus programmatically, including determining which menu is active at a given time, and which items within the active menu are available to the user. The contents of this chapter constitute about 13 percent of the OCP Exam 4 test content.
Creating Menu Modules
In this section, you will explore the following points related to creating menu modules:
This section lays the groundwork of knowledge you need to create your own menus and toolbars. You will start by being introduced to the components of a menu and the Menu Editor. With that as a basis, you will then learn how to create custom horizontal and vertical menus, how to easily generate horizontal and vertical toolbars containing buttons corresponding to items in your menus, and how to create context-sensitive pop-up menus that appear when the user right-clicks on an object.
Form Builder provides a Menu Editor enabling you to design menus graphically. Shown in Figure 19-1, the Menu Editor provides a layout that will be familiar by now: a toolbar of buttons at the top providing quick access to often-used functions, a drop-down list to change what object is being viewed, and a design area in which you do your work graphically. In addition, starting the Menu Editor alters Form Builders menus, replacing the View and Navigator menu categories with a single Menu category.
Figure 1: Menu Editor sample screen
When you build a custom menu, the menu itself cannot do any work; it serves only to organize the objects contained within it. The main menu organizes individual menus. Each individual menu organizes menu items, which provide access to the actual functions you build into the menu system. While all of these different types of objects are stored in a single menu module (.mmb) file, they have a hierarchical relationship with each other. This is reflected within the Object Navigator by a traditional tree layout. Figure 19-2 depicts how selecting an item in the Menu Editor causes that item to be selected in the Object Navigators object tree. The reverse is also true: select an item in the Object Navigators object tree and it will be selected in the Menu Editor as well.
In the Menu Editor, individual menus can be expanded or collapsed by clicking on the arrow to the right of each menu name. For instance, in Figure 19-1 the File, Edit, and Tools menus are all open, and to the right of each of their names is a small, hollow upward-pointing arrow. Clicking on that arrow would cause the items in the individual menu to collapse upward; the items would no longer be visible. Conversely, the View and Help menus are closed, reflected not only be the lack of menu items beneath them, but by the small, solid, downward-pointing arrow to the right of their names. Clicking on that arrow would cause the menu to expand, exposing its items.
To the left of each menus top-left corner is a small gray tab. This is the menu handle, which allows you to drag the entire menu from place to place.
Figure 2: Menu item selection coordination
Creating, Saving, and Attaching Menu Modules
To create a menu, you start by adding a new menu module to Form Builder. To do this, click on the Form Builder Menus node, followed by the Create button. Change the menus name to SOUND_MENU. Then, double-click on your new menu module to open a Menu Editor for it. The editor will open with a single menu item whose name is MENU1 and whose label says <New_Item>. Change the label to Action and then click on the Create Right button to create an additional menu item to the right. Here is what the Create Right button looks like:
Label the new item Edit. Use the same technique to create three more menu items named Record, Field, and Help. Then return to the Object Navigator, and change the MENU1 menus name to MAIN_MENU. You now have a main menu. To create individual menus beneath the File, Edit, and Help items, return to the Menu Editor and click on the Action menu item. Then, click on the Create Down button, shown here:
This will create a new individual menu whose name will show in the Object Navigator as ACTION_MENU. Change the label of the first item in this menu so that it reads &Save (the & in front of a character indicates that the character will give one-key access to that menu choice). Click on the Create Down button again, and label the new item SEPARATOR1. Add a third item, and label it E&xit. Continue this process until your menu structure looks like the one shown in Figure 19-3.
Figure 3: Custom menu
To make the menu items labeled SEPARATOR look like standard separator lines, select them all (using ctrl-clicking), open the Property Palette, and change their Menu Item Type property to Separator. If you want to change the order of items in the menus, you can either drag the items in the Menu Editor and let them go at their new position or perform the same type of drag-and-drop within the Object Navigator. Item order in the Menu Editor and the Object Navigator is inseparably linked.
Now that you have created the menu structure, you need to write the PL/SQL code that each menu item will execute. To do this, select your own menus Action | Save item and open its Property Palette. Ensure that its Menu Item Type property is set to Plain, and that its Command Type property is set to PL/SQL. Then click on the Menu Item Code propertys value area, and a More button will appear. Click on that button, and the PL/SQL Editor will open. Enter the following code:
You can stay in the PL/SQL Editor and enter code for every other menu item. Above the PL/SQL Editors code-entry area, there is a field labeled Name that gives you access to the other menu items in the current menu. To change menus, utilize the field labeled Object. Use these now to enter the code shown in Table 19-1.
|Menu Item||PL/SQL Code|
|Action | Save||do_key('commit_form');|
|Action | Exit||do_key('exit_form');|
|Edit | Editor||do_key('edit');|
|Record | Enter Query||do_key('enter_query');|
|Record | Execute Query||do_key('execute_query');|
|Record | Next||do_key('down');|
|Record | Previous||do_key('up');|
|Record | Scroll up||do_key('scroll_up');|
|Record | Scroll down||do_key('scroll_down');|
|Record | Insert||do_key('create_record');|
|Record | Remove||do_key('delete_record');|
|Record | Duplicate||do_key('duplicate_record');|
|Field | Next||do_key('next_item');|
|Field | Previous||do_key('previous_item');|
|Field | Clear||do_key('clear_item');|
|Help | Keys||Do_key('show_keys');|
Table 1: PL/SQL Code for SOUND_MENU Menu
You now have a complete, working menu. However, your SOUND_MODULE form module does not yet know about this menu. To attach this menu to the form module, save the menu module now. Then, select its SOUND_MENU menu module object in the Object Navigator and compile it by executing the File | Administration | Compile File command. This will create a sound_menu.mmx file on your disk; it is this file that you will attach to your form. To do this, select the SOUND_MODULE form module in the Object Navigator, open its Property Palette, and change its Menu Module property from DEFAULT&SMARTBAR to sound_menu. (If you stored the menu module somewhere other than Developers default path, you will need to enter the entire file path, along with the filename.) Then, run your form. In the Forms Runtime program, execute your own menus Record | Execute menu command to populate the form with data, and then experiment with your other menu items. When you are done, exit from the Forms Runtime program and return to Form Builder.
Now that you have seen how to create a menu, you will find it useful to look at the code underlying the default menu used by the Forms Runtime program. The source file for this menu is stored in the <oracle_home>\tools\devdem20\demo\forms\ directory in a file named menudef.mmb. This .mmb file can be customized or can serve as a basis for a new menu module.
Setting Menu Properties Using the Property Palette
There are numerous menu item properties that are valuable to know about. Table 19-2 shows these properties, their locations in the Property Palette, and what they do. Some of these properties will only be used when a menu item is created, while others are candidates for real-time manipulation using built-ins, which will be covered in a future section.
|Property Node||Property Name||Function|
|Functional||Enabled||Controls whether item is available or grayed out|
|Functional||Menu Item Type||Plain Standard menu text item
Check Boolean menu item the user checks on or off
Radio Boolean item that is one choice within a larger radio menu group of mutually exclusive choices
Separator Visual separating line
Magic Item that implements predefined properties for Cut, Copy, Paste, Clear, Undo, Quit, Help, About, and Window. Predefined functionality includes item style, position, accelerator, and in the case of Cut, Copy, Paste, Clear, Quit, and Windows, functionality as well (other commands require developer to code PL/SQL commands)
|Functional||Visible In Menu||Determines whether menu item appears at all at runtime|
|Functional||Visible In Horizontal Menu Bar||Allows you to customize which menu items appear based on whether the menu is displayed horizontally (the default)|
|Functional||Visible In Vertical Menu Bar||Allows you to customize which menu items appear based on whether the menu is displayed vertically|
|Menu Security||Item Roles||Allows you to implement menu security based on database roles; this will be covered in a future section|
|Menu Security||Display Without Privilege||Determines whether menu item appears for users who do not have the privileges necessary to access it|
Table 2: Menu Item Properties
Creating Menu Toolbars
The items you create in menus can also be represented in custom toolbars very easily. All you need to do is enable the Visible In Horizontal Menu Toolbar or Visible In Vertical Menu Toolbar property in the menu items Property Palette, and specify an icon to depict the items functionality in the toolbar. To see a quick example of this in action, open your SOUND_MENU menu in the Menu Editor, select your Action | Save menu item, and open its Property Palette. Change its Visible In Horizontal Menu Toolbar property to Yes, and its Icon Filename property to rt_save. Change the same properties for the Action | Exit menu item, using rt_exit as its Icon Filename property. Then, select the Record | Enter Query menu item and instruct it to become part of a vertical toolbar by setting its Visible In Vertical Menu Toolbar property to Yes, and its Icon Filename property to rt_quer1. Do the same for the Record | Execute Query menu item, using rt_quer2 as its Icon Filename property. Then save your menu module, compile it, and run the SOUND_MODULE application. Your screen should look similar to Figure 19-4. The buttons appear in the toolbar in the same order their commands appear in the menu, so the only way to change the order of toolbar buttons is to change the order of the corresponding commands in the menu.
Tip: The icon files you just used are stored on disk in .ico files, just like those you used earlier in the book. The icons designed for runtime use start with rt_.
Figure 4: Horizontal and vertical toolbars based on custom menu
Creating Pop-Up Menus
Pop-up menus are context-sensitive "minimenus" that appear when you right-click on an object. They are intended to include only items relevant to the object they are attached to, so a robust application may have numerous pop-up menus, each of which is attached to many objects of the same type. Unlike the menu modules you just learned about, pop-up menus do not have module files of their own; they are owned by form modules. Look in the Object Navigator now, and you will see that one of the nodes beneath your form module is Popup Menus.
To experiment with making your own pop-up menus, open the SOUND_MODULE form module in the Object Navigator (if it is not already open) and double-click on its Popup Menus node to create a new pop-up menu. Change the new pop-up menus name to POPUP_TEXT. Then, double-click on the pop-up menu item to open it in the Menu Editor. Use the techniques you learned in the previous section to create a menu like the one shown in Figure 19-5. Set the menu items properties so they match the properties shown in Table 19-3. Once that is done, you must attach the pop-up menu to the item for which it will display. Pop-up menus can be attached to individual items in a data block, or to entire canvases; the latter option is useful if you want the user to be able to click on an applications background and get a pop-up menu. For this example, you will attach the pop-up menu to data block items. Open the AV_DATA_SOUND data block in the Object Navigator, select its DESCRIPTION item, and change its Popup Menu property to POPUP_TEXT. Then run your form, populate it, and right-click on the Description field. You should see your pop-up menu appear. Experiment with its functionality, and when you are done, exit from the Forms Runtime program and return to Form Builder.
Figure 5: Pop-up menu in Menu Editor
|Menu Item||Menu Item Type||Magic Item||Menu Item Code|
Table 3: Pop-Up Menu Item Properties
Managing Menu Modules
In this section, you will cover the following points about managing menu modules:
Once you have created a menu, you may find that you need to control its properties dynamically. You can use Form Builder features to modify menu properties when the menu loads, or dynamically while your application is running. You can also control access to specific menu items, ensuring that users are only able to execute commands appropriate for their work.
Controlling the Menu Programmatically
Form Builder offers a variety of built-ins you can use in your PL/SQL code to control menus programmatically. Table 19-4 lists these built-ins and provides a description of each one.
Note: Form Builder offers quite a few other menu built-ins that are included only for compatibility with older versions of the program. These include BACKGROUND_MENU, MAIN_MENU, MENU_CLEAR_FIELD, MENU_NEXT_FIELD, MENU_PARAMETER, MENU_PREVIOUS_FIELD, NEXT_MENU_ITEM, PREVIOUS_MENU, PREVIOUS_MENU_ITEM, SHOW_BACKGROUND_MENU, TERMINATE, and WHERE_DISPLAY. These built-ins will not be supported in the next major Form Builder release, so you should not use them. There are also built-ins that apply only to character-mode or block-mode environments: HIDE_MENU, MENU_REDISPLAY, SET_INPUT_FOCUS, and SHOW_MENU. If you are designing an application for a GUI environment, these built-ins will not be useful to you.
|APPLICATION_PARAMETER||Displays the current menus parameters in the Enter Parameter Values dialog box|
|FIND_MENU_ITEM||Returns the internal ID of a specified menu item|
|GET_MENU_ITEM_PROPERTY||Identifies whether a specified menu item is checked, enabled, or visible; can also return the menu items label|
|ITEM_ENABLED||Identifies whether a specified menu item is enabled; equivalent to GET_MENU_ITEM_PROPERTY( menu_item, ENABLED )|
|MENU_SHOW_KEYS||Displays runtime Keys screen for a menu module|
|QUERY_PARAMETER||Displays a Query Parameter dialog box containing current substitution parameters|
|REPLACE_MENU||Replaces current menu for all windows in an application with specified menu|
|SET_MENU_ITEM_PROPERTY||Modifies a menu items checked, enabled, or visible properties; can also set the menu items label|
Table 4: Menu Built-Ins
Customizing Menu Modules with Substitution Parameters
Form Builder has a feature allowing you to specify code that it will run when a menu module is loaded at run time. It operates like an ON-NEW-MENU-INSTANCE trigger would, if such a trigger existed. This startup code is useful for initializing substitution parameters, which are variables that your menu items command statements can reference. The menu startup code is also useful for initializing global variables, setting menu items initial display states, and setting the initial status of check and radio menu items. This is a menu-level property, and can be entered by selecting the menu module in the Object Navigator and double-clicking on the Startup Code property. You can also create your own substitution parameters, if you wish. A full treatment of the use of substitution parameters in menu startup code is beyond the scope of this book, so this section will serve as an introduction you can follow up with on your own if you wish.
Form Builder comes with six built-in substitution parameters, which are shown in Table 19-5. All substitution parameter names are two characters long.
|Substitution Parameter Name||Data Returned|
|AD||Directory storing current menus runtime file|
|LN||Current language preference|
|PW||Password for current user|
|SO||Menu item currently selected (stands for Selected Option)|
|UN||Name of current user|
Table 5: Form Builder Built-In Substitution Parameters
Implementing Menu Security
Any form you build will automatically be limited by whatever security is in place on your Oracle server. In addition, you can also implement your own security in the client application so that certain menu items are grayed out or do not appear at all. This menu security is based on database rolesthe group-rights feature built into Oracle server. Once you have roles active in your database, you can identify which roles may use which menu items.
Note: If you are not familiar with database roles, refer to the Oracle documentation on the create role and grant role commands before continuing with this chapter.
Menu security is implemented entirely within the menu module. There are three steps to implement menu security:
For your convenience as a developer, there is a menu-module-wide property that determines whether menu security is implemented; this allows you to disable menu security temporarily for development purposes without having to alter your menu settings on an item-by-item basis. Turning this property on is the first step toward implementing menu security. To see this in action, open your SOUND_MENU menu module in Form Builder. Select the menu module in the Object Navigator and open its Property Palette. Locate the Use Security property under the Menu Security node and set the property to Yes. If you try to run your SOUND_MODULE form now, the form will load, but the menu attached to it will not.
Next, you need to tell the menu module which database roles will be candidates to access its items. To do this, double-click on the Module Roles property. You will be presented with a dialog box in which you will enter the names of the database roles that should be able to access the menu. Surprisingly, Form Builder does not have the ability to query the database and present you with a list of roles to choose from; you have to type the role names manually. Enter the DBA role now, as well as any other roles you want to add; for instance, clerk, manager, and administrator are common role types. Then click on the OK button to continue.
The last step is identifying which roles may access each menu item. You can do this in either the Object Navigator or the Menu Editor. Whichever method you choose, you can use traditional multiple-selection techniques to set the access roles for multiple menu items simultaneously. To do this from the Object Navigator, open the Menus node, followed by the MAIN_MENU node, and then the Items subnode beneath it. Select all five of the top-level menu items, and then in the Property Palette double-click on the Item Roles property. You will be presented with the list of role names you established earlier in the menu-level Module Roles property. Select one or more roles to access this menu item and then click on the OK button to continue. Repeat this process for the items within the individual menus, and be sure that at least one menu item is not set to give you access, so you have proof at run time that menu security as a whole is working. When you are done, save your menu module, compile it, and then run your SOUND_MODULE form. When you are done, exit from the Forms Runtime program and return to Form Builder.
Controlling Menu Security Programmatically
There are two built-ins that are especially useful for implementing menu security. The first is REPLACE_MENU, which changes what menu is displayed. The second is SET_MENU_ITEM_PROPERTY, which lets you control which menu items are enabled or visible in real time. For the SET_MENU_ITEM_PROPERTY built-in to work, you must set each items Display Without Privilege property to Yes. While it may seem advantageous to have items not display when the user does not have the privileges to use them, if you do so you cannot control the items properties programmatically, and therefore cannot make them visible again. Setting this property to Yes enables you to control an items properties programmatically, including whether it is visible.
In this chapter, you have covered a substantial amount of information about working with menu modules. The topics covered included creating menu modules, attaching them to form modules, and controlling the operation of menu modules when they run.
The first area you covered was identifying the components of menus and the Menu Editor. The menus you create start with a main menu, which contains one item for each of the individual menus. The individual menus consist of menu items, each of which performs a specific task such as Cut or Copy. The Menu Editor provides a graphical interface through which you can create and modify your menus. It displays a handle adjacent to the top-left corner of each menu; you can drag these handles to move menus from place to place. You can also move the menu items to different locations simply by dragging and dropping them. The menus and menu items are displayed both in the Menu Editor and in the Object Navigator; selecting an object in one selects it in the other at the same time. You can change the order of items from either place. You can add a separator to a menu by adding a menu item and setting its Item Type property to Separator. You can also make individual menu items accessible with a letter of your choosing by preceding the letter with an ampersand character (&) in the menu items Label property.
Once you have created the menu structure, you need to write the PL/SQL code that each menu item will execute. You do this through the menu items Menu Item Code property, which opens a PL/SQL Editor. Finally, you compile the menu module and then attach it to a form module by setting the form modules Menu Module property to the name of the menu module.
You can see the source file for the default Forms Runtime menu by opening the menudef.mmb file in the <oracle_home>\tools\devdem20\demo\forms\ directory.
There are numerous properties related to menu items that are valuable to know about. Some of these properties will only be used when a menu item is created, while others are candidates for real-time manipulation using built-ins. These properties include Enabled, which controls whether the menu item is available or grayed out; Menu Item Type, which specifies whether the menu item is a standard menu text item, check item, radio group, pre-defined magic function, or separator; Visible In Menu, which determines whether the menu item appears at all at run time; the property pair Visible In Horizontal Menu Bar and Visible In Vertical Menu Bar, which allow you to customize which menu items are visible depending on whether the menu is displayed horizontally (the default) or vertically; Item Roles, which allows you to implement menu security based on database roles; and Display Without Privilege, which determines whether a menu item is visible to users who do not have the privileges necessary to access it.
Next, you learned how to create toolbars whose buttons provide shortcuts to menu item functionality. These toolbars can be either horizontal or vertical. To create them, select the desired menu item and enable either the Visible In Horizontal Menu Toolbar or Visible In Vertical Menu Toolbar property in the Property Palette. (You can enable both, although there is rarely a reason to do so.) You must then specify an icon file to depict the items functionality in the menu. Menu toolbars created in this way display buttons in the same order that the corresponding commands appear in the menu, so the only way to change the order of toolbar buttons is to change the order of commands in the menu. You can also create pop-up menus, which are context-sensitive "minimenus" that appear when you right-click on an object. You can also attach a single pop-up menu to many objects, on many canvases, within the form module that owns it.
After establishing the basic premises of creating menu modules, your attention turned to managing them. You can control menus programmatically using a variety of built-ins. These include APPLICATION_PARAMETER, which displays the current menus parameters in the Enter Parameter Values dialog box; FIND_MENU_ITEM, which returns the internal ID of a specified menu item; GET_MENU_ITEM_PROPERTY, which identifies whether a specified menu item is checked, enabled, or visible, and can also return the menu items label. Additional built-ins for controlling menus programmatically include ITEM_ENABLED, which identifies whether a specified menu item is enabled; MENU_SHOW_KEYS, which displays a runtime Keys screen for a menu module; QUERY_PARAMETER, which displays a Query Parameter dialog box containing current substitution parameters; REPLACE_MENU, which replaces the current menu for all windows in an application with a specified menu; and SET_MENU_ITEM_PROPERTY, which modifies a menu items checked, enabled, or visible properties, and can also set the menu items label.
The next topic you covered was customizing menu modules with substitution parameters. Form Builders menu-level Startup Code property allows you to specify code that will be run when a menu module is loaded at run time. This startup code is useful for initializing substitution parameters, which are variables that your menu items command statements can reference. The menu startup code is also useful for initializing global variables, setting menu items initial display states, and setting the initial status of check and radio menu items. Form Builder comes with six built-in substitution parameters: AD, which returns the directory storing the current menus runtime file; LN, which returns the current language preference; PW, which returns the password for the current user; SO, which returns the menu item currently selected; TT, which returns the terminal type; and UN, which returns the name of current user. You can also create your own substitution parameters.
The last topic covered was implementing menu security, which allows you to make specific menu items unavailable or keep them from displaying at all based on the database role assigned to the user. Menu security is implemented entirely within the menu module. There are three steps to implement menu security: enable the security function in the menu module as a whole, identify the database roles that have access to the menu module, and then identify which roles may access each menu item. You enable menu security using a menu modules Use Security property. Next, you identify which database roles will be candidates to access menu items by typing the role names into a list in the menu modules Module Roles property. Finally, you assign those roles to menu items using the item-level property Item Roles.
There are two built-ins enabling you to control menu security programmatically. REPLACE_MENU allows you to change which menu is displayed, as well as the role the menu is to use. SET_MENU_ITEM_PROPERTY lets you control which menu items are enabled or visible in real time. For SET_MENU_ITEM_PROPERTY to work, you must set each items Display Without Privilege property to Yes; this enables you to control item properties programmatically.
All in all, this chapter comprises about 13 percent of the material tested on OCP Exam 4.