Newton 2.x Q&A Category: System Services, Find, and Filing

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.

System Services, Find, and Filing


Preventing Selections in the Find Overview (2/5/96)

Q: When I use ROM_compatibleFinder in Newton 2.0, the overview of found items contains checkboxes for each item, allowing the user to attempt to route the found items. Since my found items are not soup items, various exceptions are thrown. How can I prevent the checkboxes?

A: What you do depends on how you want to handle your data. There are basically two cases. The first case is when you want no Routing to take place (Routing refers to Delete, Duplicate, and the ability to move the data using transports like Beam or Print). The second case is when you want some or all of the Routing to occur.

The first case is easy. Just add a SelectItem slot to the result frame, set to nil.
For example:
    AddArraySlot(results, 
          {_proto: ROM_compatibleFinder,
            owner: self,
            title: mytitle,
            SelectItem: nil,   // prevents checkboxes
            items: myresults});

The second case is more complex. The problem is that there are many variants. The best strategy is to override the appropriate methods in your finder to gain control at appropriate points. This may be as simple of overriding Delete to behave correctly, or as complex as replacing GetTarget and adding appropriate layouts. See the Newton DTS Q&A "Creating Custom Finders" for more information.


Creating Custom Finders (2/5/96)

Q: My application uses more than one soup, so ROM_soupFinder is not appropriate, but ROM_compatibleFinder seems to throw many exceptions. Which should I use?

A: The answer depends on how much modification you will make. What you need is documentation on how they work and what you can override:

Each of the finder base protos (soupFinder and compatibleFinder) are magic pointers, so can create your own customizations at compile time.

So to do a soupFinder based item you could do something like:

DefConst('kMySoupFinder, {
    _proto: ROM_soupFinder,

    Delete: func()
    begin
        print("About to delete " & Length(selected) && "items") ;
        inherited:Delete() ;
    end,
}) ;


Most of these routines are only callable by your code. They should not be overwritten. Those routines that can be safely overriden are specified.

Some of methods and slots are common to both types of finders:

finder.selected

An array of selected items stored in an internal format. All you can do with this array is figure out the number of selected items by taking the Length of this array.

finder:Count()

Returns an integer with the total number of found items.

finder:ReSync()

Resets the finder to the first item.

finder:ShowFoundItem(item)

Displays the item passed. item is an overview item that resides in the
overview's items array.

finder:ShowOrdinalItem(ordinal)

Display an item based on the symbol or integer passed in ordinal:
'first - the first found item
'prev - the previous item
'next - the next item
<an-integer> - display the nth item based on the integer.

Under no circumstances should you call or override:
        finder:MakeFoundItem

        finder:AddFoundItems



ROM_SoupFinder

SoupFinder has the following methods and slots:

All the documented items from the simple use of soupFinder as documented in the Newton Programmer's Guide 2.0.

soupFinder:Reset()

Resets the soupFinder cursor to the first found entry. In general, you
should use the ReSync method to reset a finder.

soupFinder:ZeroOneOrMore()

Returns 0 if no found entries, 1 if one found entry or another number
for more than one entry.

soupFinder:ShowEntry(entry)

causes the finding application to display entry. This may involve
opening the application and moving it to that item.
This does not close the findOverview.

soupFinder:SelectItem(item)

mark the item as selected.
If this method is set to nil in the soupFinder proto, items will not have a checkbox in front of them (not selectable).

soupFinder:IsSelected(item)

Returns true if the item is selected.

soupFinder:ForEachSelected(callback)

Calls callback function with each selected item. The callback function has one argument, the entry from the soup cursor.

soupFinder:FileAndMove(labelsChanged, newLabel,
storeChanged, newStore)

File and/or move the selected items.
newLabel is the new label if and only if labelsChanged is true.
newStore is the new store if and only if storeChanged is true.

Developers can override this, though they may want to call the inherited routine to do that actual work. Note that FileAndMove can be called even if no items are selected. If you override this method you MUST check if there are selected items by doing:

    if selected then
        // do the work


soupFinder:FileAs(labels)

Deprecated. Do not use.

soupFinder:MoveTo(newStore)

Deprecated. Do not use.

soupFinder:Delete()

Deletes all selected items from read/write stores.

Developer can override. Note: if you override this, the crumple effect will
still happen. There is no way to prevent the ability to delete the items or
prevent the crumple effect at this time.

soupFinder:GetTarget()

Returns a cursor used by routing.

The following methods should not be called or modified:
    soupFinder.MakeFoundItem
soupFinder.AddFoundItems



ROM_CompatibleFinder

compatibleFinder:ShowFakeEntry(index)

Show the index'th item from the found items. Note that items will likely be an array of the found items.

ShowFakeEntry should behave just like ShowFoundItem. In other words, it should open the application then send a ShowFoundItem to the application.

compatibleFinder:ConvertToSoupEntry(item)

Return a soup entry that corresponds to the item. item is an item from the found items array.

The following methods are defined to be the same as the soupFinder:
        FileAs, MoveTo, Delete, IsSelected, SelectItem,
    ForEachSelected, GetTarget, FileAndMove


Note that this causes problems in some cases: most notably, the ForEachSelected call is expected to return an array of soup entries. The chances are you will need to override most of those methods. See soupFinder for a description of what the methods are supposed to do.


How to Interpret Return Value of BatteryStatus (5/6/96)

Q: I am trying to determine whether the Newton device is plugged in and to obtain other battery status information. Many slots have a nil value in the frame returned by the BatteryStatus global function. How do I interpret these values?

A: A value of nil is returned if the underlying hardware cannot determine the correct information. Some hardware is limited in the amount of information that it can return. Future hardware may fill in more slots with authoritative non-nil values.


How to Create Application-specific Folders (5/14/96)

Q: I would like to programmatically create folders so that they are available as soon as the application is open. What is the best approach to add application-specific folders?

A: You can use the global functions AddFolder and RemoveFolder to modify the folder set for a given application.

AddFolder(newFolderStr, appSymbol)

newFolderStr
- string, the name of the new folder
appSymbol - symbol, application for local folder
result - symbol, the folder symbol of the newly added folder.

AddFolder takes a folder name and creates a new folder for the application.

AddFolder returns the symbol representing the tag value for the new folder. Please note that the symbol may be different from the value returned by using Intern() on the string. In particular, folder names with non-ASCII folders are supported. If a folder with the name already exists, the symbol for the pre-existing folder is returned and a new folder is not created.

There is a limit on the number of unique folders an application can support. If the limit is exceeded, AddFolder returns NIL and a new folder is not added. With the Newton 2.0 OS, the current limit is twelve global folders and twelve local folders.

RemoveFolder(folderSym, appSymbol)

folderSym
- symbol, the folder symbol of the folder to remove
appSymbol - symbol, the application for which to remove the folder
result - undefined; do not rely on the return value of this function.

RemoveFolder can be used to remove a folder from the available list for an application. If items exist in a folder that is removed, the only way users can see the items is by selecting "All Items" from the folder list.


Changing ProtoStatusButton Text in ProtoStatusTemplate (1/15/97)

Q: I am using a protoStatusTemplate-based view and am trying to rename the primary button through the protoStatusTemplate's setup frame. After doing this, I get an exception when I tap on the renamed button. What am I doing wrong?

A: You are not doing anything wrong. There is a bug in protoStatusTemplate which will cause the primary button to function incorrectly if you do not include a buttonClickScript in the setup frame.

When you specify a frame in the primary slot of the values frame of the setup, the primary button uses the text slot and the buttonClickScript slot of that frame to initalize itself. Unfortunately, it does not check to see if either of those slots exist before trying to use them. The result is that an exception is thrown when you tap the button.

To work around this bug you must add a buttonClickScript to the primary frame. From that method you will typically call your base view's CancelRequest method.

Here is a code example:

// Add a buttonClickScript method which just calls the application's CancelRequest method.
local viewSetValues :=  {
    primary: 
        {
        text: "Stop", 
        buttonClickScript: func() GetRoot().(kAppSymbol):CancelRequest('userCancel)
        }
    };
                    
local viewSet := {
        appSymbol: kAppSymbol, 
        name: "The Name", 
        values: viewSetValues
        };
            
// Setup the status template
statusView:ViewSet( viewSet );