Editing the stack script and revising menusThe stack script contains handlers that create and delete cards. We commented out these handlers in HyperCard because they contain menu commands that MetaCard does not recognize. We are going to change those handlers to work with the new menus now.
We want to be able to use the card management handlers from the File menu button, but we neglected to include either a "New Card" or a "Delete Card" menu item when we built our initial menu group. We are also going to need a "Print Stack" command, which we'll change slightly to say "Print Records". We will add those items now.
Double-click the File button name in the Control Browser to see the Properties dialog. Click the "Extras" tab in the dialog. Insert these three lines at the top of the existing button contents list (the third line is a hyphen):
In addition, after the Print Card menu item, add a new line:&New Card/N &Delete Card -
Close the properties dialog, and edit the script of the File menu button. Change the menuPick handler to this:Print &Records
By the way, it isn't necessary to place the case statements in the same order as the menu items. It does makes them easier to locate in the script though.on menuPick which switch which case "New Card" newCardHandler break case "Delete Card" deleteCardHandler break case "Save" save this stack break case "Page Setup" answer printer break case "Print Card" if the short name of this bg = "records" then print this card from "0,38" to "512,380" else beep break case "Print Records" printRecords break case "Quit" quit break end switch end menuPick
The Print Stack menu item
In the HyperCard stack, users who wanted to print out the entire set of records could choose the "Print Stack" menu item and print only the marked cards. Since MetaCard has no built-in printing engine, we will write our own records-printing handler. While we're still in the File menu button script, add the following new handler at the end:
This is a very basic printing handler which will print each card on a separate page. There are a number of different ways to adjust the printout to print 2 or more cards per page, or just the designated text, or even a formatted report with pictures and graphics, but that is beyond the scope of this tutorial.on printRecords answer "Print all records in this stack?" with "Cancel" or "Print" if it is "cancel" then exit to top push cd repeat with x = 1 to the number of marked cds go marked cd x print this card from "0,38" to "512,380" end repeat pop cd end printRecords
Close and save the button script, and, if necessary, exit the background editing mode. Save the stack to disk.
Open the stack script and look at the doMenu handler that we commented out before the import. We have moved the newCardHandler and deleteCardHandler calls to the File menu, so we won't need to trap those two items here. The cut card condition is there to prevent a user from removing a card using one of the default menu items in HyperCard; since our MetaCard menus don't include a "cut card" item, we don't need to account for it. Similarly, the paste card condition also prevents a user from activating one of HyperCard's default menu items, but since we aren't going to include that item in our menus either, we don't need to disallow it -- the user won't have the opportunity to paste cards. Therefore the entire doMenu handler is superfluous in the MetaCard stack. Delete this handler from the script entirely.
Now change newCardHandler as indicated in red:
HyperCard's domenu "new card" command has been replaced by MetaCard's create card syntax. The tabkey command has been replaced by the command to select the text of the "Product Name" field. This would have worked in HyperCard too.on newCardHandler if short name of this bg is "Records" then set cursor to busy create card mark this card put (number of this card - 2) && "of" && \ (number of cards of this bg) into bg field "Card#" makeIndexMenu select text of fld "product name" else answer "Sorry, you must be in the Records section to add a new card." end if end newCardHandler
Now rewrite the indicated lines in deleteCardHandler:
MetaCard honors exit to HyperCard for HyperCard compatibility, so you can leave those references in the script alone, though exit to MetaCard or exit to top are two other ways to write the same thing. In this handler, tabkey has again been replaced with a command to select the text of the first field. The exit to HyperCard statement that occurred just before the first else statement has been removed entirely. It was there originally as a work-around to avoid a problem in HyperCard. Hypercard removes the insertion point from a field if the last line of the script is not the one that selected the text. This glitch requires a HyperCard script to do an immediate exit after a text selection. MetaCard doesn't have this problem, so the exit workaround isn't necessary.on deleteCardHandler if short name of this bg is "Records" then if number of cards of this bg = 1 then answer "Delete this card?" &return&return&\ "(This is currently the only record card, so" && \ "it will be replaced with a new card.)" \ with "Cancel" or "Delete" if it is "Cancel" then exit to HyperCard lock screen repeat with x = 1 to 11 put empty into bg field x end repeat makeIndexMenu unlock screen select text of fld "product name" else answer "Are you sure you want to delete this card?" \ with "Cancel" or "Delete" if it is "Cancel" then exit to HyperCard set cursor to busy lock screen delete this card if the short name of this bg is not "Records" then go to previous card makeIndexMenu end if else answer "Sorry, you can't delete this card." end deleteCardHandler
The doMenu "delete card" instruction has been replaced with MetaCard's delete this card command.
Below that is the makeIndex handler which creates the dynamic index. We will use most of it, changing only a few lines so that they work with the MetaCard menus. The original script inserted each product name into the menu as a menu item and assigned a menu message to it. Instead, we will just create a return-delimited list and assign it as the menu button contents. Since the menu button's script already knows how to work with the list, that's all the new indexing script needs to do. Remove the temporary stub we inserted before, and uncomment the original handler. Here is the revised script:
Note that this script does not add parentheses to the listing of an untitled card, which the HyperCard version displayed in the menu as (Untitled #1). The Mac OS uses the left parentheses as an indicator in menus that the menu item should be disabled, and so does MetaCard, though a work-around for this is planned for the next MetaCard release. Meanwhile, disabling the menu item isn't what we want. We have chosen to simply remove the parentheses, though they could also have been replaced with a different character instead, such as square brackets.on makeIndexMenu -- updates Index menu global gNumUntitled put "1" into gNumUntitled repeat with i=1 to the number of cards of bg "Records" set cursor to busy get line 1 of bg field "Product Name" of card i of bg "Records" if it is not empty then put it & return after theIndexList else put "Untitled #" & gNumUntitled & return after theIndexList add "1" to gNumUntitled end if end repeat put theIndexList into bg btn "Index" of grp "menuGroup" end makeIndexMenu
Close and save the script by typing the Enter key or clicking the OK button at the bottom of the script editor.
Starter Kit users: At this point, you will not be able to save the revised script because it is longer than the limits imposed by the starter kit. Cancel out of the script editor and close the stack. A prepared tutorial stack, containing the completed stack script revisions and all other changes up to this point, is available for your use. Download a copy of this partially-completed stack and use it to pick up the tutorial right here where you left off.
All contents copyright (C) 1996, HyperActive Software. All rights reserved.
Revised: December 3, 2001