Newton 2.x Q&A Category: Built-In Apps and System Data

Copyright © 1997 Newton, Inc. All Rights Reserved. Newton, Newton Technology, Newton Works, the Newton, Inc. logo, the Newton Technology logo, the Light Bulb logo and MessagePad are trademarks of Newton, Inc. and may be registered in the U.S.A. and other countries. Windows is a registered trademark of Microsoft Corp. All other trademarks and company names are the intellectual property of their respective owners.


For the most recent version of the Q&As on the World Wide Web, check the URL: http://www.newton-inc.com/dev/techinfo/qa/qa.htm
If you've copied this file locally, click here to go to the main Newton Q&A page.
This document was exported on 7/23/97.

Built-In Apps and System Data


There Is No ProtoFormulasPanel (2/5/96)

Q: The current documentation says to use protoFormulasPanel for RegFormulas, but there does not appear to be such a template.

A: You are correct, there is no such template. You use a protoFloatNGo as your base and add your formula elements to it. The only requirements are:

1. There must be an overview slot that contains the text to show in the formula's overview.

2. viewbounds.bottom must be the height of your panel.

3. There must be a protoTitle whose title slot is the name of the formula panel.


ProtoPrefsRollItem Undocumented Slots (2/6/96)

Q: When I try to open my own system preference, I get a -48204 error. The preference registers OK with the RegPrefs function.

A: The documentation on protoPrefsRollItem is incomplete. You must define an overview slot which is the text to show in the overview mode. You can optionally define an icon slot which is an icon for the title in the non-overview mode (a title icon). Note that title icons are much smaller than normal icons.


SetEntryAlarm Does Not Handle Events (2/6/96)

Q: I tried to set the alarm of an event using the SetEntryAlarm calendar message, but the alarm is not set.

A: It turns out that SetEntryAlarm will not find events. You need to use a new Calendar API called SetEventAlarm. This function is provided in the Newton 2.0 Platform File. See the Platform File Notes for more information.


How to Avoid CardFile Extensions "Still needs the card" (5/9/96)

Q: I have a package that registers a data definition and view definition for a new card type for the Names application. If the package is installed on a card and the card is removed, the user gets the following error message:

"The package <The package name> still needs the card you removed. Please insert it now, or information on the card may be damaged."

How can I avoid this problem?

A: Currently, the cardfile AddLayout method requires that the symbol in the layout is internal. This bug will be fixed in a future ROM. To work around this, do the following:

local newLayout := {_proto: GetLayout("A Test Layout")};
newLayout.symbol := EnsureInternal (newLayout.symbol);
GetRoot().cardfile:AddLayout(newLayout);

For more information about issues for applications running from a PCMCIA card, see the article "The Newton Still Needs the Card You Removed"


How to Find Distance Between Two Points on the Earth (6/7/96)

Q: Is there an API which calculates the distance between two points on the Earth?

A: Yes. In the Newton 2.0 ROM there is a global function called CircleDistance which takes two longitude/latitude pairs and the units to use in reporting the distance, and CircleDistance returns the distance between the two points. NTK may give a warning about "Unknown global function 'CircleDistance'". This warning can be safely ignored so long as you're writing a package for a Newton 2.0 OS device.

CircleDistance (firstLong, firstLat, secondLong, secondLat, units)

Returns the distance between the two points. The distance is an integer. Currently CircleDistance rounds the distance to the nearest ten miles or ten kilometers.

firstLong: The longitude for the first point on the Earth.
firstLat: The latitude for the first point on the Earth.
secondLong: The longitude for the second point on the Earth.
secondLat: The latitude for the second point on the Earth.
units: A symbol specifying the units in which the distance will be calculated. Currently the options are 'miles or 'kilometers.

Note: the longitude and latitude arguments need to be integer values of the type used by NewCity. Check the section titled "Using the Time Zone Application" in the Built-In Applications and System Data chapter of the Newton Programmer's Guide for information on how to convert a longitude or latitude in degrees, minutes & seconds to an integer for CircleDistance.


Avoiding Query Bug in GetExtraIcons Call (8/2/96)

Q: Some calls to GetExtraIcons result in an undefined Query method exception. How can I fix this?

A: There is a bug in the implementation of GetExtraIcons. The code is not checking if the store has any extras information on it, so the Query message is getting sent to a NIL soup. The result is the exception.

At this time it is not clear if or when this bug will be fixed. I suggest you use the following workaround code when you call GetExtraIcons:

    try
        GetExtraIcons(...)
        // do whatever you need to do here
        
    onexception |evt.ex.fr.intrp;type.ref.frame| do
    begin
        // check for a problem calling the Query function
        if currentException().data.errorCode = -48809 AND
                currentException().data.symbol = 'Query then
        begin
            // no extras drawer info on the store
        end ;
        else
            // a real error has occured, so let system handle it
            ReThrow() ;
    end ;


How to Get Labels for Custom Names Fields (8/13/96)

Q: The Names application allows the user to add custom fields. If I have a specific entry, the cardfile method bcCustomFields returns the labels and values of the custom fields used in the entry. Is there a way to get a list of all the custom fields the user has defined?

A: Yes, you can pass 'customFields to the names soup method GetInfo. This will return a frame of all the custom fields the user has defined. Each slot in this frame will have a frame with a 'label slot. Each 'label slot will be a string specified by the user. Here is an example:
    GetStores()[0]:GetSoup(ROM_CardFileSoupName):GetInfo('customFields)

...which returns:
{custom1: {label: "Customer Label"}, 
 custom2: {label: "Another label"}}


How to Add Confidential Owner Data (10/1/96)

Q: If I add confidential information to the Newton owner's card, all the information is beamed when the user beams the owner card. How can I keep confidential information from being sent?

A: Every owner entry has an owner slot, the value of which is a frame. This slot is removed from the entry before it is sent to another Newton device. You can add slots to this frame to store them, but keep them from being sent. Be sure to append your developer signature to any slot names you add to the owner frame.

Note that this only applies to the built-in Beam transport; any other transport or application can access all the slots in the Owner entry.


Adding Notes to Closed Notes Application (1/14/97)

Q: How do I add a note to the soup without having to have the Notepad application open? MakeTextNote doesn't work if Notes is closed.

A: You should use MakeTextNote to create the data, then add it to the soup entry using soup:AddXmit or uSoup:AddToStoreXmit (or one of the other soup functions.)

MakeTextNote always creates a frame with all the correct data that the Notes application requires. If the 2nd paramater (addit) is TRUE, it will add that frame to the Notes soup and show the note on the screen. If addIt is NIL, then the frame is returned.

It's the adding and showing that require the Notes app to be open, not the frame creation. For instance, to add a note to the default store, do something like:

    newNote := GetRoot().paperroll:MakeTextNote("Here is a sample note", nil);
    GetUnionSoup("Notes"):AddToDefaultStoreXmit(newNote, '|appSym:SIG|)


TapAction Slot Requires Text Slot to be Present (1/15/97)

Q: I have an autopart that I want to display an About slip when tapped. I added a tapAction slot but it does not work. What is missing?

A: The system will ignore the tapAction slot if it does not find a 'text slot in the partFrame as well. The 'text slot contains the name that will be displayed in the Extras drawer.

The following lines will correctly add a tapAction to a your part frame (in other words, your autopart):

    DefineGlobalConstant('kTapActionFn,
func()
begin
    // your code goes here! 
end);

// part MUST have a text slot for tapAction to be used
// text slot is the name seen by the user in Extras
SetPartFrameSlot('text, kAppName) ;
SetPartFrameSlot('tapAction, kTapActionFn) ;


Getting the Current Set of Multi-User Names (3/17/97)

Q: How can I get a list of all the students when a unit that supports it (for instance, the Apple eMate 300) is in multi-user mode?

A: The multi-user mode is implemented by the Home Page built-in application, and the list of users is stored in that application's preferences frame. Use GetAppPrefs to get the prefs for that application for read-only purposes. Only the documented slots in that frame should be accessed. Other slots are neither documented nor supported, and their behavior may change. You should also check to ensure that the Home Page application exists on a particular unit before using any features. For example, here is a code snippet that evaluates to an array of user names, or NIL if the unit does not support multiple users or is not in multi-user mode.

    if GetRoot().HomePage then
         begin
            local prefs := GetAppPrefs('HomePage, '{});
            if prefs.users and prefs.kMultipleUsers then
                foreach item in prefs.users collect item.name;
        end;


The Home Page preferences frame contains the following slots that may be accessed read only:
kMultipleUsers: non-nil if multi-user mode is enabled
kRequirePassword non-nil if passwords required in multi-user mode
kDisallowNewUsers non-nil if new users can't be created at login
users array of user frames or NIL.

A user frame contains the following slot that you may use as read-only data:
name a string, the user-visible user's name

Keep in mind that new users could be created or existing users names may be changed at any time, and there is no notification when this happens. If necessary, you should check the set of users when your application launches. It is unlikely that new users will be created, deleted, or renamed while an application is open, unless this happens as a result of a new user being created at login. In this case, registering for change in the user configuration frame with RegUserConfigChange and watching for the 'kCurrentUser slot to change will let you catch changes to the current set of multi-user names.


NEW: Registering an Auxillary Button for Newton Works (5/12/97)

Q: When I register an auxiliary button for Newton Works using the global function RegAuxButton, I get a -48204 error. Why am I getting this error?

A: This error is caused by a bug in Newton Works. You will get a -48204 error if you register an auxiliary button for Newton Works while Newton Works is closed. To work around this problem, catch that particular exception and ignore it. Here is a code example:

    try
        RegAuxButton( kAppSymbol, {destApp: 'newtWorks, ...} );
    onexception |evt.ex.fr| do
        nil;


NEW: How to Create Newton Works Documents (5/15/97)

Q: How do I create a Newton Works document for Newton 2.1 OS devices or later?

A: If you want to create a new "empty" stationery document, use the Newton Works method AddEntryFromStationery. For instance:
    if GetRoot().NewtWorks then

GetRoot().NewtWorks:AddEntryFromStationery(stationerySym);


If you want to create a new entry with data already in it, use the Newton Works method AdoptEntryFromStationery. To create a new entry, you must add the basic Newton Works soup entry slots and then any stationery-specific slots:

(1) Create a frame with the basic Newton Works soup entry slots as shown below:
class: Class of the item. For instance, for Draw documents, use the symbol 'drawPaper
version: Integer, the current version of the entry
title: String which is the document title
timeStamp: Creation date of the entry
realModTime: Date the entry was most recently modified

(2) Add the stationery-specific slots:

"Draw" Stationery Additional Slots

saveData: a frame with the following slots:
shapes: Required. An array of a single item, a picture as returned by the global function MakePict.
    selection:    [], // the empty array
    styles:        nil,


Warning: the above information describes only how to create a new Draw document. See the Q&A "Reading/Modifying Newton Works Data" for information on reading information from a Draw document. Slots in the saveData slot of Draw documents already in Newton Works should be treated as read-only. (Do not try to modify these data structures in any way.)

"Paper" Stationery Additional Slots

SaveData: the object returned from protoTXView:Externalize(). See the Newton 2.1 OS documentation for information about Externalize(). Note that this data must be from a protoTXView that uses VBOs (it uses the protoTXView:SetStore(...) method), or Newton Works can run out of NewtonScript memory when editing the document.

hiliteRange: frame with the document's hilite range (see the protoTXView documentation for details)

margins: a frame with slots 'top, 'left, 'bottom, 'right, which are the document's margins in pixels. The frame can also optionally have the slots 'userTop, 'userLeft, 'userBottom, and 'userRight that will contain numbers (integer or real) with the margin sizes translated to user units (inches or centimeters.) If the userXXX slots are missing or nil, they will be calculated from the pixel values.


(3) Use code like the following to add the entry to the soup:
    if GetRoot().NewtWorks then
        GetRoot().NewtWorks:AdoptEntryFromStationery(theEntry, stationerySym, GetDefaultStore());

See the Newton Programmer's Reference for more info about the NewtApplication:AdoptEntryFromStationery(...) method.


NEW: Reading/Modifying Newton Works Data (5/15/97)

Q: How do I read/write information in Newton Works documents?

A: The supported ability to read/write information from Newton Works documents depends on what type of stationery is used and what information is documented for that stationery type. For instance, word processor (paper) documents can be read and modified, whereas Draw documents can be read but not modified. If the desired Newton Works stationery is not built-in, contact the stationery's developer to determine whether reading and/or modifying the soup entry data is supported.

Related APIs: To create new Newton Works documents, see the Q&A"How to Create Newton Works Documents". To modify data in Newton Works documents that are currently viewed, see the Newton 2.1 documentation for information about APIs to the word processor (Paper stationery) and the Draw application (Draw stationery) APIs for tools and stamps.

For reading/writing information from "Paper" soup entries, see the format specified in the Q&A"How to Create Newton Works Documents" or the Newton 2.1 OS documentation.

For "Draw" soup entries, we support creating new documents (see the Q&A "How to Create Newton Works Documents") and reading shapes from documents that have been viewed in Newton Works already. However, there is no support for manipulating individual shapes of a current soup entry, nor examining shapes in items that have been created/imported, but never viewed in the Newton Works application.

To read shape information from pictures, here is the information about how to extract shapes from valid Draw documents.

The entry has the basic Newton Works soup entry slots as shown below:
class: Class of the item. For instance, for Draw documents, use the symbol 'drawPaper
version: Integer, the current version of the entry
title: String which is the document title
timeStamp: Creation date of the entry
realModTime: Date the entry was most recently modified

The Draw document soup entry also has the slot called saveData that contains the following slots:
shapes: This is an array of shapes in the document.
styles: An array of all styles contained in the shapes array.
selection: An array containing integer indexes into the shapes array, indicating the currently selected shapes.

The shapes slot is represented as an array of style/shape pairs, as returned by drawApp:GetContents(). Each "shape" can be another array of shape and style pairs, representing grouping of shapes (these grouping can continue, so subarrays can have sub-subarrays, etc). If the shapes array contains exactly one item (its length is 1) and the class of the item is 'picture, it is a picture that has been created/imported but not yet viewed in Newton Works. If this is the case, the individual shapes cannot be read, but the picture is the same format as the return value of the global function MakePict.

Warning: Slots in the saveData slot of Draw documents already in Newton Works should be treated as read-only. Do not try to modify these data structures in any way. Manipulating them can result in serious user problems.


NEW: Opening a Specified Document in Works (5/27/97)

Q: How do you make Newton Works open a particular document?

A: The easiest way is to use the ShowFoundItem method of the Works base view only as shown below. ShowFoundItem is generally intended for internal use by the application itself. However, it provides handy access for navigating to a particular soup entry, so Works supports using it for this purpose only. Do not attempt to use ShowFoundItem to do more than simply bring up an entry in the Works application.

The 2nd argument (the finder) to ShowFoundItem may be difficult to specify because Works can use stationery provided by 3rd parties, which may have special requirements for the finder. In Works, the stationery is responsible for adding data to the finder when a find is performed, and so the stationery may rely on that data being present when ShowFoundItem is later used. For all the stationery types that exist at the time this Q&A was written, a minimal finder frame of {findWords: [""]} is sufficient to allow the stationery to show the item. Please note that this is NOT a fully specified finder, however it is sufficient for the FindSoupExcerpt method, which is used widely. A full finder frame which accomplishes the same thing might look like this:
    {owner: GetRoot().NewtWorks,
     findType: 'text,
     findWords: [""],
     items: [{_proto: theEntry, title: "None"}]}


For Works stationery developers, we recommend not making any assumptions about the contents of the finder frame when implementing your ViewDef's ShowFoundItem method. (Note that ShowFoundItem is a Works-specific requirement of stationery. Generic ViewDefs do not require a ShowFoundItem method.)

Here is an inspector example of navigating Works to one of each existing stationery. The example assumes a new untitled document of each type exists. (You'll want to have your own code that finds the appropriate Works soup entry to open.)
    // make sure Works is open
    GetRoot().NewtWorks:Open();

    // find an entry
    s := GetUnionSoup("NewtWorks");
    theEntry := s:Query({text: "Untitled Paper"}):Entry();

    // show it
    GetRoot().NewtWorks:ShowFoundItem(e, {findWords: [""]});

    // the rest of them
    theEntry := s:Query({text: "Untitled Drawing"}):Entry();
    GetRoot().NewtWorks:ShowFoundItem(e, {findWords: [""]});

    theEntry := s:Query({text: "Untitled Calculations"}):Entry();
    GetRoot().NewtWorks:ShowFoundItem(e, {findWords: [""]});

    theEntry := s:Query({text: "Untitled Spreadsheet"}):Entry();
    GetRoot().NewtWorks:ShowFoundItem(e, {findWords: [""]});

    // cleanup
    theEntry := s := nil;


NEW: Creating a Works Word Processor Document with Data (6/9/97)

Q: How do I create a new Works paper document with some initial data? I'd like something like the Notes application's MakeTextNote function.

A: First, review the Q&A entitled "How to Create Newton Works Documents" for details on actually creating the document.

To create initial data for a word processor document, the simplest thing to do is to create a dummy view based on protoTXView. Use the protoTXView methods to add data to that view. When done, use the Externalize method to get the data in a form suitable for saving in the Works soup.

When creating your dummy protoTXView, it's imperative that you call the SetStore method so that the data is created on the user store rather than the NS heap. Different formats are used for store-backed and heap-backed protoTXViews, and the type of backing is carried into the Externalized data. As a result, failure to use SetStore would cause you to create a Works document that was not backed by the user store and which could eventually result in out-of-memory errors when the user added sufficient data to the document.

Here's an example of how to create a dummy text view and populate it with some initial data. You may wish to vary the store passed to SetStore in the viewSetupFormScript and AdoptEntryFromStationery, or the intial text specified in the 2nd paramater to Replace. (Notably, you may wish to provide styles for the text, see the Newton 2.1 OS documentation on the protoTXView method Replace.)

    // create and populate a dummy protoTXView
    local textView := BuildContext(
        {
            _proto: protoTXView,
            viewBounds: SetBounds(0, 0, 0, 0),
            viewFlags: 0,
            ReorientToScreen: ROM_DefRotateFunc,
            viewSetupFormScript: func() begin
                inherited:?viewSetupFormScript();
                self:SetStore(GetDefaultStore());
            end,
        });
    textView:Open();
    textView:Replace({first: 0, last: 0}, {text: "Some initial text"}, nil);

    // get the data in an external form for the Works soup
    local saveData := textView:Externalize();
    textView:Close();

    // Create a new Works document from the data
    GetRoot().NewtWorks:AdoptEntryFromStationery(
        {
            title: "Initial Title",
            saveData: saveData,
            hiliteRange: {first: 0, last: 0},
            margins: {top: 72, left: 72, right: 72, bottom: 72},
        }, 'paper, GetDefaultStore());



NEW: Unregistering Stamps in Newton Works Draw (7/2/97)

Q: When I call the Newton Works Draw stationery's UnRegStamps method, my registered stamps do not get unregistered. What is going wrong?

A: There is a bug in the Draw application's UnRegStamps method that causes stamps to remain registered. Use the following code to unregister your stamps:

local viewDef := GetViewDefs( 'drawPaper ).default;

if viewDef then
    begin
        // Call UnregStamps conditionally.  If the Draw application is not
        // installed, GetViewDefs will return the "Missing Stationery"
        // stationery.
        viewDef:?UnregStamps( kStampRegistrySymbol );

        local registry := GetViewDefs( 'drawPaper ).StampListRegistry;
        if registry AND HasSlot( registry, kStampRegistrySymbol ) then
            RemoveSlot( registry, kStampRegistrySymbol );
    end;


Note that calling the UnRegStamps method is required for future compatibility.