Telescript

Classes for supporting Telescript in Magic Cap have been removed from Rosemary.

Classes affected by these changes

AddressInvalid obsolete
Agent obsolete
ArgumentInvalid obsolete
ArgumentMissing obsolete
AttributeReadOnly obsolete
Cased obsolete
ClassAbstract obsolete
ClassException obsolete
ClassSealed obsolete
ClassUnavailable obsolete
CollectionException obsolete
Compared obsolete
ConcretePlace obsolete
ConditionUnavailable obsolete
ConditionUndefined obsolete
ConversionUnavailable obsolete
CreditCard obsolete
DivisionByZero obsolete
ElementInvalid obsolete
EncodingInvalid obsolete
EncodingUnavailable obsolete
EnginePlace obsolete
Equal obsolete
EscalationInvalid obsolete
Event obsolete
EventProcess obsolete
Exception obsolete
ExecutionException obsolete
ExistingConnectionMeans obsolete
FeatureRedefined obsolete
FeatureSealed obsolete
FeatureUnavailable obsolete
FeatureUndefined obsolete
InternalException obsolete
IRMeans
KernelException obsolete
KeyInvalid obsolete
List obsolete
LoopMissing obsolete
MMDirectoryException obsolete
MMEntryAlreadyExists obsolete
MMException obsolete
MMNoSuchEntry obsolete
MarkMissing obsolete
MatchList obsolete
MeetingAgent obsolete
MeetingDenied obsolete
MeetingDuplicated obsolete
MeetingException obsolete
MeetingPlace obsolete
MethodInvalid obsolete
MethodMissing obsolete
MiscellaneousException obsolete
ModifierInappropriate obsolete
Named obsolete
ObjectSpecifier obsolete
ObjectUnlocked obsolete
ObjectUnowned obsolete
Octet obsolete
Ordered obsolete
PackageProcess obsolete
PackageUnavailable obsolete
ParameterInvalid obsolete
ParameterMissing obsolete
Pattern obsolete
PatternInvalid obsolete
PaymentMethod obsolete
PermitChanged obsolete
PermitExhausted obsolete
PermitProcess obsolete
PermitViolated obsolete
Petition obsolete
PetitionExpired obsolete
Place obsolete
PlaceNotCurrent obsolete
PlaceScene obsolete
PositionInvalid obsolete
PrimitiveException obsolete
Process obsolete
ProcessException obsolete
ProcessNotControlled obsolete
ProcessNotCurrent obsolete
ProcessNotOwner obsolete
ProgrammingException obsolete
PropertyUndefined obsolete
ReferenceProtected obsolete
ReferenceVoid obsolete
RemoveDataAgent obsolete
RequestAgent obsolete
RequestCard obsolete
RequestDocument obsolete
Resource obsolete
ResponderMissing obsolete
ResponderNil obsolete
ResultInvalid obsolete
ResultMissing obsolete
ServiceInfoRecord obsolete
Stack obsolete
StackDepleted obsolete
StandardRegistrationPlace obsolete
TicketExpired obsolete
Uncopied obsolete
Unmoved obsolete
UploadAndAnnounceAgent obsolete
VariableUndefined obsolete
Verified obsolete
WayUnavailable obsolete

Text framework

In order to be able to display character data in any language, the API of the Magic Cap text framework has changed in Rosemary. Magic Cap supports Unicode characters in the existing text framework; Magic Cap text objects can already contain Unicode character data. However, there are many operations that take ASCII characters or Pascal style strings as parameters. The Rosemary release of Magic Cap no longer supports the use of Pascal style strings as parameter data types. All interfaces that use the String data type have been replaced with interfaces that use text objects. Operations that return text objects will also follow a new convention: if no text needs to be returned, nilObject is returned instead of an empty text object.

C literals are still legal; the Rosemary release of Magic Cap will provide versions of the C string library routines, such as strcmp() and printf(), so it will be easier to port code from other platforms to Magic Cap.

Many new operations have been added to make many types of text manipulation easier, including new routines for sorting names, and formatting numbers.

In order to be usable in other countries, Magic Cap needs to be able to display characters in languages other than English. Certain languages have characters that cannot be expressed in 8 bits of data. Since the String data type can only represent 8 bit characters, operations that use String are not useful in these countries.

Communicators will not be limited to displaying character data in one language. For example, it's entirely possible that a Japanese Magic Cap communicator can receive e-mail in another language. The message should be displayed in the language it was composed in, provided that the receiving communicator has the proper fonts to display the contents of the message.

If your package already uses text objects as the interface for character data manipulation, you're already most of the way there and will only have minor changes to make. On the other hand, if you make extensive use of Pascal strings in your package code, you will need to convert your package to use text objects.

Even if you don't plan to localize your package to other languages, users might send data from your package to a communicator that is localized to a different language. The data needs to be stored in a format that can be interpreted by the receiving communicator. For this reason, you should avoid using the String data type for parameters to your class methods.

Text objects are the preferred container for character data. In some instances, character literals will be more appropriate than text objects. For example, using a literal to represent a modem command string is perfectly valid. In these instances, you should use C style, null terminated strings to represent your data. User visible text should be defined as Text objects in your instance definition file, never inline in your code.

Rosemary also contains hot text. This feature recognizes and interprets URLs, e-mail addresses, phone numbers, person names and dates, and offers to do something useful with them when they are tapped. The functionality is implemented by class TextInterpreter.

The MakeComparable() intrinsic is used to normalize text objects so that equality can be assumed and tested for when similarity is meant. This operation returns a new, normalized text object that has been stripped of style information.

Removed the use of the String type from the Magic Cap API. All character data should be passed using Text objects, or instances mixing in with HasText, or at worst, character literals. Replaced these calls with equivalent calls that took Text parameters.

The TextInfo() method has been removed from the API. This routine took an index and returned a string base on that index. Distinct attributes have been added to replace this functionality. TextInfo() used to be declared by class Object and subclasses overrode it to deal with specific indices. Rather than declaring a glut of new attributes in class Object, created the mixin classes HasContent, HasContact and HasAddress and grouped the attributes into these classes. Three attributes remain attributes of class Object: ContentDescription(), DateAsText() and SizeInKBytes().

HasText_CopyTextRangeToBuffer is now an intrinsic operation. Additionally, the <rangeToCopy.length> field will always return the actual number of characters that were copied. This has always been the case, but was never documented. HasText_CopyTextToLiteral and HasText_ComputeTextCRC have also been changed to be intrinsic operations.

Removed the operation TextStyleCoupon_CouponText. The only purspose of this operation was to handle the case where the coupon object didn't have a name.

The operation HasText_MatchText has been removed. Call HasText_ContainsText instead.

Added the new operations HasText_RemoveTextUpToCharacter and HasText_RemoveTextUpToAndIncludingCharacter. The first method deletes any text before the character the is passed in if the character is found. The latter method removes the passed in character as well.

Moved the ReplacedContents() and ReplacingContents() methods from the TextField class to the TextContainer class.

The mixin class HasContent defines the attributes ShortContentDescription() and TypeDescription().

The mixin class HasContact defines the attributes ContactLocation() and ContactPhoneNumber().

The mixin class HasAddress defines the attributes DateReceivedAsText(), ShortDateReceivedAsText(), DateSentAsText(), ShortDateSentAsText(), RecipientName(), SenderName() and SenderOrRecipientName(), and Subject(). In previous releases of Rosemary, Subject() was called SubjectAsText().

The ValueAt() method of list views was similar to TextInfo(). It has been replaced by the CellValue() method to return the value of a given cell. You should use the new placement attributes for TextInfo related uses of ValueAt().

Introduced the operation HasCharacters(). This operation should be called to determine if a text object is empty rather than comparing the text object against nilObject.

The new text API will return ephemeral Text objects. These objects are not long lived; if you need to store a text object, you should call CopyNear() to move the text object into persistent memory. The new text API will also return nilObject rather than an empty Text object. You can use the new method NewTextIfNil() that will create a new ephemeral text object if nilObject was returned from a previous text method.

Auto-getters that return text objects will return ephemeral text objects. Text auto-getters do the equivalent work of:

return CopyText(Field());
Text auto-setters will store a copy of the text object that is passed in. They do the equivalent of
Destroy(Field());
SetField(CopyTextNear(text, self));

Added class AttributeMappedText. This is a subclass of AttributeText that remaps a text object every time another object changes.

Text mappings work differently in Rosemary to reduce the amount of shadowing that can occur. Callers of MapText() that modify the valueText (by calling ReplaceLine() on the text mapping) should create a transient copy of the text mapping instead of working with the original. TextMapping_MapAndMarkText now nils out the valueText field after mapping the text. This means that you can't set up a text mapping and then use it on multiple objects.

TextMapping_ValueFromIndex now converts sender and receiver from contacts to contact addresses so GivenName() will work. This is a hack that will have a better fix in the future.

Introduced the operation HasText_TruncateText. This routine can be used to shorten a text object to fit a text length limit (not a display width limit). Future versions of this operation will make sure not to separate combining marks from their base characters, so it's a good idea to call this operation instead of truncating in some other way.

Magic Cap 1.5 introduced the feature of one-line text fields that shrunk the font size used in the text field as entered text became too long to fit in the field. Rosemary extends this feature to work with multi-line text fields. In these fields, the size of the font will shrink when the height is too large.

The flags word of classes AttributeText and StructuredField have been split into individual Boolean fields. This makes figuring out which bits to you need to set to get the proper behaviors simpler.

The AttributeType() operation is no longer supported in the new runtime. The class AttributeText has been changed to no longer depend on it. AttributeText objects can no longer point to integer attributes. Use the new attributes SentCountAsText() and ReceivedCountAsText() instead.

The operations DrawWrapped() and DrawClipped() could be used to either draw some text or to measure it. Both operations determined which function to perform based on whether or not the canvas was nilObject. The API of these routines so that there is a distinct boolean parameter that specifies whether the routines should draw or measure instead of relying on an implied meaning of another parameter. The clip and canvas parameters have been removed at any rate for the current canvas and current clip work.

Added the attribute [Set]ModeAlteration() to class TextField. This attribute is used to specify the mode a keyboard will be in when a text field becomes active. This allows TextField subclasses to specify which two modes the mode switch on the keyboard switches between. By default, class TextField allows the keyboard to switch between kDefaultAlphabetMode and kNumbersMode. A subclass of TextField, class KeyboardModeField, overrides ModeAlteration() to tell the keyboard to switch to the mode specified by the keyboardMode field. All this is to work around the fact that there is only one bit available in TextField_fieldFlags to specify the default mode, but international systems might have different default keyboards depending on the text field.

Fixed HasText_InsertLiteral so it can insert more than hundred characters.

Added the operations HasText_AccumulateTextCRC and HasText_ComputeTextCRC which compute the CRC of just the character data in a text object while ignoring referenced objects, such as styles. These operations replace Utilities_HashText and Utilities_TextHash.

Removed support for copyAttribute_Mask in class AttributeText.

Made MainText() and StreetAddress() be attributes instead of pairs of operations.

ColumnTitle() now returns a text object instead of modifying one.

The operations MakeCharacterLowercase() and MakeCharacterUppercase() have been removed because changing case on a per-character basis doesn't always work in some languages. A new intrinsic, HasText_MakeUppercase replaces MakeCharacterUppercase(). This routine that calls the localizable case conversion interface and returns a new text object.

The class CaseConverter defines the API for localizable uppercasing. Magic Cap provides the class SystemCaseConverter with the default implementation. The indexical iDefaultCaseConverter references the default instance of this class. SystemCaseConverter uses a localizable table that defines the uppercase mappings for all characters that are mapped one to one. It may also have a multiline text object describing initial strings that should be uppercased entirely even if the caller only asks for the initial capitals; this handles the Dutch "ij" that is always mapped to "IJ". SystemCaseConverter also handles four precomposed Unicode characters that have different uppercase and titlecase variants.

Renamed the routines CharacterAt(), ReplaceCharacterAt() and DeleteCharacterAt() to xxxCharacterAfter. Other xxxAt methods in Magic Cap are one based and these routines are zero based. This makes the API more consistent.

Hitting the tab key on a card with only one text field set the current typing target to nilObject, but didn't hide the keyboard. Changed SelectNextField() to not change the typing target if there's only one text field and it doesn't have its putAwayKeyboard bit set. This makes hitting the tab key in this situation do nothing, which is the desired behavior.

Fixed a bug where text coupons dropped into size-restyling fields aren't truncated properly.

Added HasText_CopyPlainTextIfStyled. This returns self if the object has no styles, or an ephemeral style-less copy of the text otherwise.

Made HasText_TruncateText properly handle 0 as the maximumCharacters parameter. This now truncates the entire string. Fixed a bug where this method was truncating one too many characters.

Renamed TextWidth() to TextWidthInStyle().

Renamed CompareText() to CompareTextCharacters().

Fixed a bug where incorrect found items were reported when searching for text. Found text was remembered by which text field it was in. Now that forms are copied, if the text field was in a form, that text field might not exist by the time the text is displayed. Text fields are now remembered by index into the form items list rather than by ObjectID. TextSearchResult now stores a form item number instead of whether the text was in card data. This field is zero for non-form items; for form items it is the index in the form items list of the text field.

Removed task specific text mapping cases from TextMapping_ValueFromIndex.

Renamed FindMatchingLine() to FindIdenticalLine() to make it clearer the type of matching that is performed. This name more closely parallels the other matching operation, FindSimilarLine().

Many other operations have been renamed to reflect the fact that they work with Text objects instead of strings.

Old name New name
CanonicalASCIIHash ComparableASCIIHash
CanonicalCharacterMightMatch ComparableCharacterMightMatch
CopyTextRangeTransient CopyTextRange
(now returns an ephemeral)
CopyTextTransient CopyText
(now returns an ephemeral)
DateText DateAsText
DateTextFromDays DateAsTextWithFormat
DisplayNameUnflipped DisplayNameForSorting
ExtractAreaCode FindNumericPrefix
GetFieldDumpString FieldDumpText
GetLtWtName LightweightName
IntegerToText TextFromSigned
TextFromUnsigned
IntToKByteString NumeralFromKBytes
IntToBytes TextFromSigned
TextFromUnsigned
Line CopyLine
MakeCanonical MakeComparable
MakeNumberedString NumberedTextFromLiteral
MakeSearchString MakeSearchText
NumberToStr TextFromSigned
TextFromUnsigned
PlayDTMFStr PlayDTMF
SearchName SearchName
SearchNameForSorting
SetLine ReplaceLine
[Set]NameAsText [Set]Name
StringEqual IsTextIdentical
IsTextSimilar
StringToPhoneKeys MapPhoneKeys
StripLeadingWhiteSpace StripLeadingWhitespace
StripTrailingWhiteSpace StripTrailingWhitespace
(changed "whiteSpace" to "whitespace" in general)
TextFromLiteral NewTextFromLiteral
TextFromSigned SignedNumeral
TextFromUnsigned Numeral
TextToString CopyTextToLiteral
ValueString ValueAsText
VariableNameToNumber FindVariableByName
VariableNumberToString VariableName

Classes affected by these changes

AddressCard obsolete
AttributeText
AttributeMappedText new
BookPage
CanBeSearched new
Card
CaseConverter new
Character
ChoiceBox
Clock
Cluster obsolete
Control
DateTime
DialingCountry new
Drawers
EditableList
ElidedTextField new
FaxWindow
FixedList
Folder
GridView
GroupAddressCard obsolete
HasAddress new
HasContact new
HasContent new
HasIndexing
HasText
HasTranscoding new
ICFContent obsolete
Identifier
KeyboardModeField
ListCard
ListEntry
ListView
Locale obsolete
MacStream
MagicmailName obsolete
Math
MessageRecord obsolete
Meter
MonthChoiceBox
MultiLineContentListView new
NameCard
NamedStateSwitch
NoteCard
Object
OctetString
OneLineFormatter
PackageContext obsolete
PagerLabel obsolete
PeoplePhonePicker
PersonalMessage
PhoneCallCard
PhoneLabel obsolete
PhonePanel
PurgeableContents
PSTNTelescriptLabel obsolete
Report obsolete
Road
Scene
Selector obsolete
SpeedDialButton
StorageBox
StringDictionary obsolete
StructuredField
StyleChoiceBox
System
SystemCaseConverter new
SystemTextComparison new
Task
Telecard
Text
TextContainer
TextField
TextFormatter
TextInterpreter new
TextMapping
TextSearchResult new
TitledWindow
TypeIDString obsolete
Utilities
ViewableTextContainer new

Touching

Touch(), and its related calls, will sometimes move the responder object into a different cluster, but the calling routine would not know that this happened. Made the methods Viewable_Touch, Viewable_Press, Viewable_MoveTouch, and Movable_MovePress return either self, or the new transplanted self. In addition, the methods Viewable_CopyTouch, Viewable_CopyPress, and Window_DropACopy return the new copy or nilObject if no copy was made for whatever reason.

Classes affected by these changes

Viewable

Type safety

The object runtime in Magic Cap 1.x uses one namespace for integers, object IDs, class numbers and operation numbers. The shared namespace meant that these numbers could be used interchangeably. An operation could be defined to return an unsigned value, and this value could potentially be any one of the mentioned types. The new runtime model in Rosemary separates these concepts, requiring them to be non interchangeable data types.

This separation means that certain values can no longer be used interchangeably. A large amount of code currently uses 0 for nilObject and vice versa. This will no longer be allowed in Rosemary. Rosemary introduces the notions of nilClass and nilOperation for the same reason. The separation of class and operation number namespaces means that dispatching against a class number is distinct from the standard object dispatching mechanism. You can no longer create a method that can be dispatched to by either an object or by a class number; two distinct methods must be declared. Operations that are dispatched to by specifying a class number as the self parameter are declared using the class operation keyword in class definitions.

        define class Cluster;
            inherits from Object;
	
            class operation GetCurrent(): Object;
            operation SetCurrent(): Object, safe, noFail;
        end class;
The object and instance compilers have been changed to support the namespace separation. This support appears as stricter type checking at compile time. The changes to the object and instance compilers will also affect C code. Method parameter lists are checked against the operation interface defined in class definitions to make sure that they match.

New types have been defined to specify these distinct types; you can't use Unsigned to specify an operation number, intrinsic number or class number. Instead use the types OperationNumber, IntrinsicNumber and ClassNumber. Created ClassNumberList, IntrinsicNumberList, ClassOperationNumberList and ClassNumberList to hold lists of these new types of values.

Created new operations [Set]FieldValue() which are parallel to [Set]FieldOf. These operations should be used to read non-object field values.

New operations have been added to support the new data types. Macros to specify a particular cluster, like InLockedSystem() and InSystemTransient() replace the old cluster constants (kLockedSystem, kSystemTransient, etc.) You should use the new macros where you used to use the old constants, like the nearThis parameter to the Near() allocation methods.

Operations that would sometimes return an integer value and at other times return an object have been split into calls that handle a specific data type. For example, Object_Attribute has been replaced with Object_ObjectAttribute and Object_IntegerAttribute.

Callers of IntegerAttribute() that use the result as a short integer need to explicitly cast the result into a short because the new runtime does not automatically clear the high word or sign extended the result.

Existing methods that were dispatched to either by ObjectID or class number have been split into two distinct methods. Added operations ImportClassNumber(), MakeUsableClassNumber(), and MakeStorableClassNumber() to deal with class numbers. These are parallel to Import(), MakeUsable(), and MakeStorable. Methods that were only dispatched to via class numbers are now class operations. Also added MakeUsableClassOperationNumber(), MakeUsableOperationNumber() and MakeUsableIntrinsicNumber().

The names of several operations have been changed to avoid type conflicts. There used to be several classes that used the same method name for operations that really had nothing to do with each other. Some of these operations had return values that are now of different types.

The header files define a little used constant, kStopIterating, which tells iterators to stop. This constant is really an ObjectID, so replaced it with iStopIteratingConstant to keep the namespace boundary clean.

Currently, the Pointer data type in class definition files maps to any pointer type in C code. A side effect of checking method parameters against operation interfaces is that pointer types in class definitions must be distinct for Rosemary.

Stricter type checking by the compiler means that code that used to compile before might now have several compiler errors. Most of these problems can be solved by applying explicit type casts to the parameter.

Pointers are used most extensively for Init() calls, actors and iterators. The class compiler will still know only the basic Pointer data type. This means that the parameter interface of the previously mentioned types of calls should be declared to use a void pointer type, and then have the pointer parameter cast to the specific pointer type inside the routine itself. Instead of doing this:

Method void
Actor_Init(ObjectID self, NewActorParameters *params)

Do this:

Method void
Actor_Init(ObjectID self, const void *castThis)
{
   const NewActorParameters *params = (const NewActorParameters *) castThis;
}

Because of the strict parameter passing and function resulrules, prototypes for functions that dispatch an operation must match the prototype of the operation that is going to be called. This means that OperationByNumber() would only work on operations that take an integer parameter and return an integer result. Because OperationByNumber() is used for many operations that take a parameter or return a result that is other than an interger, several new versions of OperationByNumber() have been created. Be sure that you use the correct version. The new versions are OperationByNumberPassBoolean(), OperationByNumberPassShort(), OperationByNumberPassInteger(), OperationByNumberPassObject(), OperationByNumberReturnBoolean(), OperationByNumberReturnShort(), OperationByNumberReturnInteger(), and OperationByNumberReturnObject().

Because PerformConfirmationFancy() calls OperationByNumber() when the user confirms a window, new variants of this method, as well as the ConfirmationDialog class have been created. Created subclasses of ConfirmationDialog that hold a boolean or object parameter when the user confirms the window. ConfirmationDialog should be used when no parameter should be passed when the user confirms the window. ConfirmationDialogBoolean should be used when a boolean parameter is passed when the user confirms the window. ConfirmationDialogObject should be used when an object parameter is passed when the user confirms the window. New versions of PerformWithConfirmationFancy() have been created to be able to pass the different parameter types. You need to make sure that the class of the ConfirmationDialog object passed to a PerformWithConfirmationFancy() variant matches the parameter type. You should dispatch against a ConfirmationDialog when calling PerformWithConfirmationFancy(), a ConfirmationDialogBoolean when calling PerformWithConfirmationFancyPassBoolean(), and a ConfirmationDialogObject when calling PerformWithConfirmationFancyPassObject().

IntegerAttribute() and SetIntegerAttribute() call OperationByNumber() so they needed to be updated as well. New versions, ShortAttribute(), SetShortAttribute(), BooleanAttribute() and SetBooleanAttribute() have been added.

AttributeStemp called IntegerAttribute() which means it didn't workj for attributes that were booleans. AttributeStamp is now an abstract superclass that has new concrete subclasses BooleanAttributeStamp and IntegerAttributeStamp.

The BeginReadFields() and BeginModifyFields() family of calls now return typed pointers instead of void * and const void *.

Classes affected by these changes

AttributeStamp
AttibuteStep
AttributeText
Backup
BitmapFont
Canvas
Card
Citation obsolete
City
ClassNumberList new
ClassOperationNumberList new
ConfirmationDialog
Control
Debug
Dictionary
DirectConnectLabel obsolete
DisplayServer
ElectronicMailService
Exceptions
ExceptionServer
Executed obsolete
FailsafeSemaphore
FieldList obsolete
FixedList
Font
FormElement
Globals obsolete
GMTPClient obsolete
GMTPReceiver obsolete
GMTPSender obsolete
GridView
HardwareStream
HasDigest obsolete
ICFContent obsolete
Identifier
ImageChoiceBox
IndexedCollection
LANMeans obsolete
LineGeometryCacheEntry
LocalRuleAction
Lock
LookupTable obsolete
MacStream
MagicBus
MagicBusATKeyboard
MagicBusClient
MagicOperation obsolete
MailAttribute
Means
MIDISong
Object
OneClassContentListView
OperationList obsolete
OperationVersionsList obsolete
OperationNumberList new
PDU
PDUClientInterface
PDUServiceInterface
PostalLabel obsolete
PixelMap
Pixels
Place obsolete
PurgeableContents
Reference obsolete
RestrictedField
ScheduledTime
ScriptExecutionStack obsolete
ScriptExecutionState obsolete
SimpleActionButton
Sound
Speaker
SpecialButton
Stream
SystemContext obsolete
TargetedListView
TouchInput
Timer
ULongLookupTable obsolete
Utilities
Wireline obsolete