Text Editor Programming

This page describes how to program a Text Editor Object, including how to start and stop editing, how to access and change the current selection, and how to access the text being edited.

### Text Editor Object Identifier

Most of the features described below are accessed by using the objectaction statement. This statement performs actions on a specified object. Usually the object is specified by its name, which means that the object must have a name. To learn how to assign a name to an object, see Object Names.

For example, suppose the current form has a Text Editor object that you’ve given the name Notes Editor. You could start editing with this object with this code:

    objectaction "Notes Editor","open"

But remember, this will only work if you’ve set the object name to Notes Editor.

The objectaction statement also allows the object to be specified by it’s ID value. You can use the objectinfoarray( function to find out the ID you need based on particular criteria, for example the field name. Suppose you want to start editing the field Body, but you’re not sure what the object name of the Text Editor object is, or if it even has a name. You can still find out what the object ID number is and open the Text Editor object with code like this:

    let targetField = "Body"
    let targetObjects = objectinfoarray(
        {str(objectinfo("id"))},
        {objectinfo("fieldname")=targetField and objectinfo("class")="TextEditorObject"})
    if linecount(targetObjects)=1
        let targetObjectID = val(targetObjects)
        objectaction targetObjectID,"open"
    else
        beep
    endif

In this example, the objectinfoarray( function scans all of the objects in the current form.

    let targetObjects = objectinfoarray(
        {str(objectinfo("id"))},
        {objectinfo("fieldname")=targetField and objectinfo("class")="TextEditorObject"})

If it finds a Text Editor object that is associated with the Body field, the ID of that object is placed into the targetObjects array. (This formula checks to make sure that the object is a TextEditorObject because we want to skip over other types of objects that could be associated with the Body field, like data buttons, popup menus, or text lists.)

The if statment checks to make sure that we found one, and only one object.

    if linecount(targetObjects)=1

If we did find one object, we need to convert the ID value from text into a number.

    let targetObjectID = val(targetObjects)

With this ID number we can now perform actions on this object.

    objectaction targetObjectID,"open"

If the form doesn’t contain an editor object for Body, or if contains two or more such objects, this code will beep.

Note: The code above is useful as a sample, but you don’t need to ever use this code yourself. Panorama has a built in editfield statement that performs this operation in one line of code:

    editfield "Body"

Now that we know how to identify the Text Editor object that is the intended target of an action, the rest of this page will discuss the various actions that be peformed.

### Starting and Stopping Editing

The normal way to start editing a Text Editor object is to simply click on it. In code, the `"open"` action will start editing, for example:

    objectaction "Notes Editor","open"

To stop editing, use the `"close"` action:

    objectaction "Notes Editor","close"

#### The Active Editor

If a Text Editor object currently is being edited, it is said to be the active editor. You can use the info(“activeobject”) function to find out the name of the object being edited. If there is no object currently being edited, this function returns empty text (`""`).

A problem with the info(“activeobject”) function is that it only works with named objects. If you’re objects don’t have names, you can use the info(“activeobjectid”) function instead. This function returns the ID number of the object being edited, or zero if no object is being edited. (Of course you can use this function even if your objects do have names.)

This function can be used to write code to close the actively edited object even if we don’t know what object that is.

    if info("activeobjectid")<>0
        objectaction info("activeobjectid"),"close"
    endif

Performing an action on the currently edited object is so common that there is a special statement, activeobjectaction, to do it.

    if info("activeobjectid")<>0
        activeobjectaction "close"
    endif

In fact, closing the currently edited object is so common that there is also a special closeactiveobject statement.

    closeactiveobject

### Working With the Selection Range

When ever text is being edited, there is a selection range. For example, if you double click on a word, the selection range will be from the start to the end of the word. If you click on a spot, the start and end of the selection range will be the same number (this is called the insertion point).

To find out what the current selection range is, use the `"getselection"` action. This must be followed by two variables that will receive the start and end points of the selection. This code will display the number of characters currently selected. (The activeobjectaction statement is used in this example because the selection range only exists when the object is being edited, but you can use the objectaction statement if you’re sure the specified object is currently being edited.)

    local start,end
    activeobjectaction "getselection",start,end
    if start=end
        message "Insertion point"
    else
        message pattern(end-start,"# character~")+" selected"
    endif

Note: The selection range values start at zero, not one. So if the first five characters are selelected, the start of the selection will be 0 and the end of the selection will be 4.

To change the current selection range, use the `"setselection"` action. This must be followed by two values for the start and end positions of the range. This code selects the first character of the text.

    activeobjectaction "setselection",0,1

If you specify negative values, they will be counted from the end of the text. This code will select the last character of the text.

    activeobjectaction "setselection",-2,-1

To select all of the text, use:

    activeobjectaction "setselection",0,-1

To put the insertion point at the end of the text, use:

    activeobjectaction "setselection",-1,-1

To put the insertion point at the beginning of the text, use:

    activeobjectaction "setselection",0,0

It’s ok to specify a number past the end of the text. This code will probably select all of the text, even if there are only ten characters. (But to make sure, it’s better to use -1, which will work even if there are a million characters.)

    activeobjectaction "setselection",0,9999

### Working With the Edited Text

A Text Editor object is usually linked with a field or variable. But unless you’ve checked the Update Variable Every Key option, the text being edited is usually different than the value in the field or variable. To find out the what the text is currently is right this moment, use the `"gettext"` action.

    local etext
    activeobjectaction "gettext",etext

To find out what the currently selected text is, use the `"getselectedtext"` action.

    local etext
    activeobjectaction "getselectedtext",etext

To copy the currently selected text into the clipboard, you could do this:

    local etext
    activeobjectaction "getselectedtext",etext
    clipboard = etext

However, there is an easier method:

    activeobjectaction "copy"

To completely replace the edited text with new text, use the `"settext"` action. WARNING: This will discard the text that was there before, and there is no undo. For example, this code will completely clear the Text Editor object.

    activeobjectaction "settext",""

To replace the currently selected text with new text, use the `"inserttext"` action. If there is text selected, this will replace it. If there is currently an insertion point, the text will be placed at the insertion point. (Note: This operation can be reversed with the Undo command.)

This code adds today’s date to the end of the currently edited text. But if there’s not already a blank line at the end of the edited text, it adds one, so that the date is on a line by itself.

    local etext
    activeobjectaction "setselection",-1,-1
    activeobjectaction "gettext",etext
    if etext<>""
        let lastCharacter = etext[-1,-1]
        if lastCharacter <> lf()
            activeobject "inserttext",lf()
        endif
    endif
    activeobject "inserttext",datepattern(today(),"DayOfWeek, Month ddnth, YYYY")

If you want to delete the currently selected text, you can do this:

    activeobjectaction "inserttext",""

But you can also do this:

    activeobjectaction "clear"

If you want to delete the currently select while copying it to the clipboard, you can do this:

    activeobjectaction "cut"

See Also

- activeobjectaction -- allows a procedure to communicate with the object on the current form that is currently being edited (if any).
- changeobject -- modifies the properties of one object in a form.
- changeobjects -- modifies the properties of one or more objects in a form.
- cloneform -- copies all of the objects in a form (optionally, with modifications) into the active form.
- cloneobjects -- duplicates objects in a form (with modifications).
- closeactiveobject -- closes any object whose text is currently being edited.
- datamode -- switches a form from graphics mode into data mode.
- deleteobject -- deletes the specified object from the current form.
- deleteselectedobjects -- deletes selected objects from a form.
- draggraybox -- facilitates dragging something around in a form window.
- dragtext -- starts drag-and-drop of text.
- formcleanview -- cleans up extraneous NSView objects in the current form.
- formxy -- programmatically scrolls a form to a new position.
- graphicsmode -- switches a form into graphics mode.
- info("activeobject") -- returns the name of the currently active text editor or word processor object (if any).
- info("activeobjectid") -- returns the object ID of the currently active text editor or text list object, if any.
- info("activesuperobject") -- returns the name of the currently active text editor or word processor object, if any.
- info("click") -- returns the location of the last mouse click in screen relative coordinates.
- info("clickedobjectid") -- returns the object ID of the clicked object.
- info("focusobject") -- returns the name of the currently active text editor or word processor object, if any.
- info("focusobjectid") -- returns the object ID of the currently active text editor or text list object, if any.
- info("scrollpoint") -- returns the distance the current form is scrolled horizontally and vertically.
- magicformwindow -- designates an open window as the temporary active window for the purposes of info( functions and graphic statements.
- magicwindow -- designates an open window as the temporary active window for the purposes of info( functions and graphic statements.
- magnification -- changes the magnification of a form.
- Matrix Programming -- programming a Matrix object.
- Modifiable Object Properties -- describes the properties of graphic objects that can be modified by a program (dimensions, color, font, title, etc.).
- newformobject -- creates a new graphic object in a form.
- object -- selects an object (based on the object name).
- objectaction -- allows a procedure to communicate with an object on the current form.
- objectid -- selects one graphic object in the current form based on an ID number.
- objectinfo( -- returns information about a graphic object: its location, size, color, font, etc.
- objectinfoarray( -- builds a text array of form object properties
- objectnumber -- identifies one graphic object from a set of selected graphic objects in the current form.
- openasyncprogresswindow -- opens a floating progress window for asynchronous operations (urltask(, timers).
- progressalert -- displays a progress alert if an operation is going to take a long time.
- progressbar -- updates a progress bar on the current form.
- selectallobjects -- selects all the graphic objects in the current form.
- selectnoobjects -- unselects all the graphic objects in the current form.
- selectobjects -- uses a formula to select one or more objects in the current form.
- startgraphicschange -- adds undo support to a procedure.
- Text Display Programming -- programming a Text Display Object.
- Text List Programming -- programming a Text List Object.
- textlisttableoptions -- sets up text list table options
- Web Browser Programming -- programming a Web Browser Object (including JavaScript).
- xytoxy( -- converts a point or rectangle from one co-ordinate system to another.

History

Version | Status | Notes
10.0 | New | New in this version.