Programming Guide: Binding

# Programming Guide

## Binding

Binding is the run-time process of assigning executable code to instance data. For parts, binding is the assignment of the correct part editor to a given part. For example, when the stored data of a part is to be brought into memory, OpenDoc binds a specific part editor to that data, loads the editor (if it has not already been loaded), and transfers control to the editor so that it can read in the data of the part. The resulting combination of part editor bound to part data constitutes the part object in memory, including both state and behavior.

On opening a document, OpenDoc binds editors to all parts that need to be displayed. During execution, OpenDoc binds part editors to part data when a part is read in or when its editor is changed. OpenDoc may unload part editors at various times, especially if memory is low. Also, when a part needs more memory, the document shell can unload the part editors used by inactive parts. Thus a given part editor may need to be bound and loaded more than once in a session.

The interface to the binding process is not entirely public. OpenDoc accomplishes it with the help of the binding object (class ODBinding). The binding object combines part-kind and part-category information provided by part editors, part-kind information stored with parts, and preferences specified by users to choose an editor for each part accordingly.

### Information Used for Binding

This section describes the information your part editor must provide to make binding work correctly.

#### Part Kinds Supported by an Editor

For binding of parts to editors, these two kinds of information need to be available to OpenDoc:

- Your part editor must register information about the data formats it handles. OpenDoc uses this information to construct name space objects that it uses to bind part editors to parts.

- Your stored parts must include information about the data formats in them.

OpenDoc decides which editor to bind to a given part based on the part kind and part category of the data. Part kind is a typing scheme, analogous to file type, that can include specifications of data type, creator application, and even version. Part kinds are ISO strings such as "text", "WaveDraw:Bitmap", or "AcmeDB:Kind:FlatDataBase". Part-editor developers define the part kinds that their editors use; each kind is a specific data format that the editor understands.

##### Tokenized Strings

At run-time, OpenDoc and part editors often manipulate ISO strings as tokens (short, regularized representations of the strings). Before passing ISO strings to OpenDoc, you therefore may need to convert them to tokens with the Tokenize method of the session object.

The fact that part editors can store multiple representations of their parts also means that they are not necessarily confined to reading and editing a single part kind. Your WaveWriter 3.01 Pro editor, for example, may be capable of reading and writing data of WaveWriter 1.0 ("WaveWriter:Kind:StyledText") and plain text ("text") format, as well as its own preferred format ("WaveWriter:Kind:IntlText").

At a minimum, your part editor needs to store only your own preferred part kind. A better alternative is to store your preferred kind plus one common standard public format. Beyond that, you should probably store additional formats only on user instruction, to keep your stored parts from being too large.

#### Part Kinds Stored in a Part

Your part editor stores each of its parts in a format, or part kind, that your editor recognizes. But your part is not limited to one part kind per part; it can have multiple stored representations of its data in a single part. You store different representations in the kODPropContents property of your part's storage unit, as value streams with different value types, arranged in order of fidelity.

Fidelity refers to the faithfulness of a given representation to a part editor's native, or preferred, part kind. For example, assume that you store a part created with your WaveWriter 3.01 Pro part editor as three separate representations with the following part kinds: "WaveWriter:IntlText", "WaveWriter:StyledText", and "text". The highest-fidelity representation is "WaveWriter:IntlText", which represents the native format of your part editor; the "WaveWriter:StyledText" representation is an older, simpler format that lacks some of the latest WaveWriter features; and the "text" representation is plain, unformatted ASCII text.

Storing part representations in order of fidelity is crucial to ensuring that the best available editor is bound to a part.

##### Standard Part Kinds

To increase the chances of your parts being readable in all situations, you should if possible store at least one widely readable part kind, in addition to your editor's preferred part kind, every time you write your part to storage.

#### Part Categories Supported by an Editor

Part category is a typing scheme similar to part kind, except that it defines only a broad classification of the data manipulated by a part editor Like part kinds, part categories are ISO strings; they have designations such as "plain text", "3D graphics", "time", or "sound". (The full ISO string for the styled-text category, for example, is "OpenDoc:Category:Text:Styled").

Your part editor must specify the part categories corresponding to the part kinds it supports. Your editor registers, for each part kind that your editor can read and write, the part category or categories that the part kind belongs to. (A part kind can correspond to more than one part category; for instance, an unstyled text part could belong to both "plain text" and "styled text" part categories).

Table 13 lists the part categories that OpenDoc currently recognized and briefly explains the general kind of stored data each represents.

Table 13. Part Categories

Part Category | Explanation
--- | ---
kODCategoryPlainText | Plain ASCII text
kODCategoryStyledText | Styled text
kODCategoryDrawing | Object-based graphics
kODCategory3DGraphic | 3D object-based graphics
kODCategoryPainting | Pixel-based graphics
kODCategoryMovie | Movies or animations
kODCategorySampledSound | Simple sampled sounds
kODCategoryStructuredSound | Sampled sounds with additional information
kODCategoryChart | Chart data
kODCategoryFormula | Formula or equation data
kODCategorySpreadsheet | Spreadsheet data
kODCategoryTable | Tabular data
kODCategoryDatabase | Database information
kODCategoryQuery | Stored database queries
kODCategoryConnection | Network-connection information
kODCategoryScript | User scripts
kODCategoryOutline | Outlines created by an outliner program
kODCategoryPageLayout | Page layouts
kODCategoryPresentation | Slide shows or other presentations
kODCategoryCalendar | Calendar data
kODCategoryForm | Forms created by a forms generator
kODCategoryExecutable | Stored executable code
kODCategoryCompressed | Compressed data
kODCategoryControlPanel | Data stored by a control panel
kODCategoryControl | Data stored by a control, such as a button
kODCategoryPersonalInfo | Data stored by a personal information manager
kODCategorySpace | Stored server, disk, or subdirectory (folder) data
kODCategoryProject | Project-management data
kODCategorySignature | Digital signatures
kODCategoryKey | Passwords or keys
kODCategoryUtility | Data stored by a utility function
kODCategoryMailingLabel | Mailing labels
kODCategoryLocator | Locators or addresses, such as URLs
kODCategoryPrinter | Stored printer data
kODCategoryTime | Stored clock data

Part category is not included in the information stored with a part; only part editors store information about the categories of the part kinds they manipulate. OpenDoc uses that information at run-time to help the user define a default editor for each category.

#### User Strings

OpenDoc manipulates editor names, part kinds, and part categories as tokenized ISO strings. However, as noted in the following sections, there are several points at which the user can intervene in the binding process, and ISO strings are not appropriate for user display. OpenDoc requires that user-readable text be in the form of international strings that can be in any script or language.

Therefore, your part editor needs to provide, in its registration methods, user strings for its editor name, part kinds, and part categories so that OpenDoc can display them to the user at the appropriate times. The user-readable name of your part editor (in English) might typically be close to, but not exactly the same as, its ISO string name and the kinds of parts it creates. For example, WaveWriter 3.0 might be the user-readable name of a part editor whose editor ID (ISO string name) is WaveCorp:WaveWriter 3.0 and whose native part kind is WaveCorp:WaveWriter:IntlText.

### Binding Process

This section describes when binding occurs and how OpenDoc decides which editor to bind to a part, depending on which editors are available on the user's machine.

#### When Binding Occurs

Part binding occurs whenever your part is instantiated, typically when OpenDoc or another part calls the CreatePart or AcquirePart method of your draft. For example, binding can occur in the following situations:

- When a draft opens, OpenDoc binds a part editor to each visible part.

- As the user adds parts to an open document, OpenDoc binds part editors to the new parts.

- Drawing a part requires part binding if OpenDoc has not already bound an editor to the part.

Binding can thus occur in many different situations, not just when a part's document first opens. Your part editor needs to be able to function with any part to which it has just been bound, including a part that it has never edited before.

#### Binding to Preferred Editor

The most obvious binding for a part is to the editor that created it. A stored part may have, in its storage unit, a property of type kODPropPreferredEditor that specifies the editor that last edited the part. That editor is considered the preferred editor of the part. It may be the editor that originally created the part, or it may be an editor that was later bound to it. Every time a new editor is bound to a part, that editor becomes the part's preferred editor and remains so until a different editor is bound to the part.

When OpenDoc searches for an editor to bind to a part, it looks first for the preferred editor. If the preferred editor is present, OpenDoc binds it to the part.

If the preferred editor is not present on the user's system, or if there is no property of type kODPropPreferredEditor in the part, OpenDoc examines in turn each of the part kinds in the stored part, from highest fidelity to lowest, seeking to match that part kind with a part kind supported by an editor on the user's system. OpenDoc first examines the part's preferred kind (if the kODPropPreferredKind property exists), and then searches the remaining part kinds from highest fidelity to lowest (that is, from first to last in the contents property).

For each part kind under consideration, OpenDoc attempts to find an editor in this priority order:

- Default editor for kind
- Default editor for category
- Any available editor

The following sections describe each of these steps.

#### Binding to Default Editor for Kind

After the preferred editor, the highest-priority binding for a part is to the default editor for kind, the user's chosen default editor for all parts of the part kind under consideration. For every part editor installed on a user's system, OpenDoc maintains a table that specifies the part kinds for which that editor is the default editor.

By setting the default, the user chooses, for example, a single favorite text editor for processing any text part of a given part kind (when the part's preferred editor is not available). Figure 70 shows the OpenDoc Registry dialog, which displays the default editors chosen by the user.

Figure 70. The Preferred Editor Selection Dialog Box

View figure.

The "Part Kind List" list box displays a list of all the part kinds. The "Part Editor List" list box lists only editors that can handle the selected part kind.

If, for the part kind under consideration, OpenDoc finds its default editor for kind, OpenDoc binds that editor to the part.

Part editors for a specific part kind are displayed by double clicking on a part kind in the list box. A list of part editors are displayed in the button list box with the preferred editor highlighted. The user can change the preferred editor for the selected part kind by clicking on the new part editor in the list box and then clicking on the OK button.

#### Binding to Default Editor for Category

If, for the part kind under consideration, there is no specified default editor for kind, OpenDoc looks for the default editor for the part category (or categories) of that part kind. As with the default editor for kind, OpenDoc maintains a list of the user's choice for default editor for each part category. By setting this default, the user chooses, for example, a single favorite graphics editor for editing any kind of bit maps (when its preferred editor and the default editor for its kind are not defined or not available).

Part editors for a specific part kind are displayed by double clicking on a part kind in the list box. A list of part editors will be displayed in the bottom list box with the preferred editor highlighted. The user can change the preferred editor for the selected part kind by clicking on the new part editor in the list box and then clicking on the OK button.

#### Binding to Any Available Editor

If there is no default editor for the category of the part kind under consideration, OpenDoc then searches for any editor in the system that can read that part kind. If it finds such an editor, OpenDoc binds the editor to the part.

In the previous example, if the text part editor cannot read the part's kind, then OpenDoc looks for an editor that can.

If this attempt fails, OpenDoc repeats the entire process for each of the remaining (lower-fidelity) part kinds in the part. It looks first for the default editor for that kind, then the default editor for its category, and finally any editor that can read it.

Returning to the same example, suppose that the part has also stored a plain text version of its data. On the second round, OpenDoc locates the default editor for the plain text and binds it to the part. In this case, style information would be lost, but the user would still be able to read and edit the part.

This example illustrates the obvious advantage of having multiple stored representations of your part. The user has a better chance of being able to open and use some form of your part, even when your part editor is not available. Default editors exist only to allow the user to express a preference for an individual editor when a part's preferred editor is not present.

#### Binding to Editor of Last Resort

If there is no part editor on the user's machine that can read any of the part kinds stored in a part, the part remains unviewable and uneditable. However, OpenDoc still binds an editor to the part so that the part's document can be opened. This is the editor of last resort; it is always available.

On viewing the editor of last resort's properties, OpenDoc displays the part kind of the highest-fidelity version of the part. The user can use that information to determine what editor to purchase in order to read the part.

The editor of last resort never modifies the part it displays; it does not change the part kinds or their storage order in the part's storage unit.

### Consequences of Changing Part Editors

As a result of the binding process, your part editor can be bound to a part that it had not previously edited. (Binding to your editor is especially likely if the user has specified your editor as the preferred editor of that part's kind or category). This binding may occur in these situations:

- The part's document opens on a machine that does not have the part's previous editor, and your part editor can read its part kind or else the user translates the part to a kind that your editor can read.

- The user, using the Paste as command, pastes a part into a document and either specifies your part editor as the preferred editor or specifies that the part be translated to a part kind readable by your part editor.

- The user, in a part's Properties notebook or a document's Properties notebook specifies your part editor as the preferred editor or changes the part's kind to a part kind readable by your part editor.

- The user makes a copy of a document with the Document menu's Save a copy command and specifies a part kind for the root part that is readable by your part editor.

In each of these situations, once the binding occurs, the part's storage unit contains at least one part kind that your editor can read. However, the stored data in the part may not necessarily have exactly the same part kinds, in exactly the same order, that your editor would normally write into a part's storage unit. In this case, OpenDoc calls your part's ChangeKind method, passing it the new part kind.

OpenDoc can also call your part's ChangeKind method at times other than when your part editor is bound to a part. If your part editor supports more than one part kind and the user has specified (for example, in the Part Info dialog box or Document Info dialog box) that your current part's kind be changed to another kind that your part editor can read, OpenDoc calls your part's ChangeKind method and passes it the new part kind. This is the interface to ChangeKind:

    void ChangeKind (in ODType kind);

Your part editor needs to start manipulating the part's data in the new format. Your ChangeKind method must store the data in an order that reflects your own fidelities. It should also make sure that the new part kind is specified in the part's kODPropPreferredKind property.

For example, suppose that your WaveWriter 1.1 part editor supports only "WaveWriter:StyledText" and "text" formats. Suppose further that your editor is bound to a part whose highest-fidelity part kind is "WaveWriter:IntlText" (perhaps originally created with the WaveWriter 3.0 editor) but that also contains a "WaveWriter:StyledText" representation. In this case, you need to make sure that "WaveWriter:StyledText" is specified as the preferred kind when you subsequently write the part. You could also include a "text" representation, which must be stored after the preferred kind. (If your part editor supports it, you can optionally write a higher-fidelity version than the preferred kind; if you do, you must place it before the preferred kind in your storage unit).

Note:

> These modifications do not occur if the editor of last resort is bound to a part. It never modifies the part to which it is bound and it does not change the part kinds of the values, or their fidelity ordering, in the part's storage unit.

[ Top | Previous | Next | Contents | Index | Documentation Homepage ]