com.adobe.xfa.text.TextEditor Maven / Gradle / Ivy
Show all versions of aem-sdk-api Show documentation
package com.adobe.xfa.text;
import com.adobe.xfa.gfx.GFXEnv;
import com.adobe.xfa.ut.CoordPair;
import com.adobe.xfa.ut.IntegerHolder;
import com.adobe.xfa.ut.Rect;
/**
* A text editor provides interactive access to a text stream, with
* methods that map to user-interface events.
*
* The text editor contains a text range, which is its key into the
* underlying text stream. Text editor methods manipulate the
* underlying text through that range, as well as the range itself.
* When the range is non-empty it corresponds to a selected range of
* text in the application. When the range is empty, it corresponds to
* a caret. The text range interacts with XTG Graphic Services to
* ensure that it displays these states properly. It also interprets
* method calls based on the range's state. For example, inserting a
* character in caret mode simply inserts the character at the (empty)
* range location. Inserting a character in selected range mode deletes
* the contents of the range before the insertion occurs.
*
*
* A text editor also may carry a reference to a graphic environment.
* In an interactive application, this is important, as it allows for
* scrolling and invalidation.
*
*
* This class supports a number of text unit movement operations, for
* example, move by character or word. These operations include the
* notion of a forward or backward move, which can be interpreted in
* either a logical or a visual sense. Logical moves apply to the
* underlying text stream data. Moving forward operation increases the
* position's stream index, while moving back operation decreases it.
* For visual moves, forward implies to the right and backward to the
* left. In right-to-left text, forward is synonomous with decreasing
* index and backward with increasing index. In right-to-left text,
* forward corresoponds to increasing index and backward corresponds to
* decreasing index. The caller choses logical or visual mode in the
* parameter list of movement operations. For visual moves to be
* effective, there must be a text display associated with the stream.
* Note that a text editor defaults to visual moves on Mac and logical
* on Windows, while a text position always defaults to logical moves.
*
*
* Many text editor methods are declared virtual. While not necessarily
* call-backs, they do allow the application to trap operations in a
* common place, its derived object.
*
*
* For more information, please see the extenral documentation.
*
* @exclude from published api.
*/
public class TextEditor {
public static final boolean LOGICAL_DEFAULT = true;
private TextRange moRange = new TextRange();
private GFXEnv mpoGfxEnv;
private boolean mbUpdateDisplay;
private Rect moPrevExtent;
/**
* Default constructor.
*
* Create a text editor that has no stream association and no graphic
* environment.
*/
public TextEditor () {
mbUpdateDisplay = true;
}
/**
* Copy constructor.
*
* Copy all data from the source editor, including range and graphic
* environment reference.
* @param oSource - Source text editor to copy.
*/
public TextEditor (TextEditor oSource) {
moRange.copyFrom (oSource.moRange);
mpoGfxEnv = oSource.mpoGfxEnv;
mbUpdateDisplay = oSource.mbUpdateDisplay;
}
/**
* Constructor with graphic environment.
*
* The editor will be associated with the graphic environment, but its
* range will be initially unassociated.
* @param poGfxEnv - Graphic environment. May be NULL, in which case
* there is no initial graphic environment.
*/
public TextEditor (GFXEnv poGfxEnv) {
mpoGfxEnv = poGfxEnv;
mbUpdateDisplay = true;
}
/**
* Constructor with text stream and graphic environment.
*
* The editor will be associated with the given stream (through its
* range) and the given graphic environment.
* @param poStream - Stream to associate range with. May be NULL
* indicating no initial association.
* @param poGfxEnv - (optional) Graphic environment. May be NULL
* (default) indicating no initial graphic environment association.
* @param bSelectAll - (optional) If TRUE, set up the editor's range to
* initially select the entire stream. Note that if the stream is
* empty, the editor starts out in caret mode. If FALSE (default), the
* range starts out in caret mode, at the end of the stream.
*/
public TextEditor (TextStream poStream, GFXEnv poGfxEnv, boolean bSelectAll) {
mpoGfxEnv = poGfxEnv;
mbUpdateDisplay = true;
associate (poStream, bSelectAll);
}
/**
* Constructor with range and graphic environment.
*
* The editor's range will be copied from the given range, and its
* graphic environment will be set from the given parameter.
* @param oRange - Source text range to copy for this editor's range.
* @param poGfxEnv - (optional) Graphic environment. May be NULL
* (default) indicating no initial graphic environment association.
*/
public TextEditor (TextRange oRange, GFXEnv poGfxEnv) {
mpoGfxEnv = poGfxEnv;
mbUpdateDisplay = true;
associate (oRange);
}
/**
* Constructor with position and graphic environment.
*
* Initialize the editor's range in caret mode at the specified
* position.
* @param oPosn - Source position object.
* @param poGfxEnv - (optional) Graphic environment. May be NULL
* (default) indicating no initial graphic environment association.
*/
public TextEditor (TextPosnBase oPosn, GFXEnv poGfxEnv) {
mpoGfxEnv = poGfxEnv;
mbUpdateDisplay = true;
associate (oPosn);
}
/**
* Associate the editor with a new text stream.
*
* The editor will be associated with the given stream (through its
* range). Does not change the graphic environment.
* @param poStream - Stream to associate range with. May be NULL
* indicating no association.
* @param bSelectAll - (optional) If TRUE, set up the editor's range to
* initially select the entire stream. Note that if the stream is
* empty, the editor starts out in caret mode. If FALSE (default), the
* range starts out in caret mode, at the end of the stream.
*/
public void associate (TextStream poStream, boolean bSelectAll) {
TextRange oNewRange = new TextRange();
if (bSelectAll) {
oNewRange.associate (poStream);
} else {
oNewRange.associate (poStream, Integer.MAX_VALUE, Integer.MAX_VALUE);
}
moveComplete (oNewRange);
}
/**
* Associate the editor with a new text range.
*
* The editor's range will be copied from the given range. This may
* simply be a new range in the current stream or it may refer to a
* different stream. Does not change the graphic environment.
* @param oRange - Source text range to copy for this editor's range.
*/
public void associate (TextRange oRange) {
TextRange oNewRange = new TextRange (oRange);
moveComplete (oNewRange);
}
/**
* Associate the editor with a new position.
*
* Assign the editor's range from the given text position object,
* setting it up in caret mode. Does not change the graphic
* environment.
* @param oPosn - Source position object. This may be a position in the
* same stream or it may refer to a new stream altogether.
*/
public void associate (TextPosnBase oPosn) {
TextRange oNewRange = new TextRange (oPosn.stream(), oPosn.index(), oPosn.index());
moveComplete (oNewRange);
}
/**
* Change the editor's range by index number.
*
* Change the range's start and end index number, maintaining the
* association with its current stream.
* @param nIndexStart - New starting index number for the range. If too
* large, it will be truncated.
* @param nIndexEnd - New endting index number for the range. If too
* large, it will be truncated. Note that the caller may give these
* numbers in the wrong order and the editor will sort it out
*/
public void associate (int nIndexStart, int nIndexEnd) {
TextRange oNewRange = new TextRange (moRange.stream(), nIndexStart, nIndexEnd);
moveComplete (oNewRange);
}
/**
* Associate the editor by stream and user indexes.
*
* A user index corresponds to a position where a caret may be placed.
* While there are distinct positions surrounding an embedded attribute
* change, there is only a single user index there.
* @param poStream - Stream to associate with.
* @param nIndexStart - New starting user index number for the range.
* If too large, it will be truncated.
* @param nIndexEnd - New ending user index number for the range. If
* too large, it will be truncated. Note that the caller may give these
* numbers in the wrong order and the editor will sort it out
*/
public void userAssociate (TextStream poStream, int nIndexStart, int nIndexEnd) {
TextRange oNewRange = new TextRange (poStream,
userIndexToStreamIndex (poStream, nIndexStart),
userIndexToStreamIndex (poStream, nIndexEnd));
moveComplete (oNewRange);
}
/**
* Query the current user indexes associated with the stream.
*
* A user index corresponds to a position where a caret may be placed.
* While there are distinct positions surrounding an embedded attribute
* change, there is only a single user index there.
* @param nIndexStart - Current starting user index number for the range.
* @param nIndexEnd - Current ending user index number for the range.
*/
public void getUserPosition (IntegerHolder nIndexStart, IntegerHolder nIndexEnd) {
nIndexStart.value = streamIndexToUserIndex (moRange.stream(), moRange.start().index());
nIndexEnd.value = streamIndexToUserIndex (moRange.stream(), moRange.end().index());
}
/**
* Obtain the editor's current range.
* @return Current text range represented by this editor.
*/
public TextRange range () {
return moRange; // TODO: C++ implementation returns a const ref
}
/**
* Change the editor's range.
*
* This method is identical to the overload of Associate() that takes a
* text range parameter.
* @param oNewRange - New range to use.
*/
public void range (TextRange oNewRange) {
associate (oNewRange);
}
/**
* Query the graphic environment currently in use.
* @return Pointer to graphic environment currently held by this text
* editor. May be NULL.
*/
public GFXEnv gfxEnv () {
return mpoGfxEnv;
}
/**
* Change the graphic environment.
* @param poNewGfxEnv - Pointer to new graphic environment to use. May be
* NULL.
*/
public void gfxEnv (GFXEnv poNewGfxEnv) {
mpoGfxEnv = poNewGfxEnv;
}
/**
* Query the status of the UpdateDisplay flag.
*
* For information on this flag, please see the second UpdateDisplay()
* overload.
* @return Current value of the UpdateDisplay flag.
*/
public boolean updateDisplay () {
return mbUpdateDisplay;
}
/**
* Change the UpdateDisplay flag.
*
* Each editor instance carries an UpdateDisplay flag which indicates
* whether the editor should attempt to make changes to the graphic
* display as it manipulates the underlying text stream. These updates
* include invalidation on changes as well as showing and hiding the
* caret. To have any effect, there must be an associated graphic
* environment. To get invalidation, there must be an associated
* stream, and it must have a text display. The default value of this
* flag is TRUE, indicating that display updates are intended.
* @param bNewUpdateDisplay - New value for the UpdateDisplay flag.
*/
public void updateDisplay (boolean bNewUpdateDisplay) {
mbUpdateDisplay = bNewUpdateDisplay;
// if (mbUpdateDisplay) {
// ShowCaret();
// } else if (mpoGfxEnv != null) {
// mpoGfxEnv.windowCaretHide();
// }
}
/**
* Move ahead/back one character in the underlying text stream.
*
* This corresponds to the right and left arrow keys in the Windows
* user-interface.
* @param bForward - (optional) If TRUE (default) move forward one
* character. if FALSE, move back that amount.
* @param bSelect - (optional) If TRUE, start or extend the selection
* represented by this editor. In other words, the range's anchor is
* not changed; its loose end moves ahead/back one character. If FALSE
* (default) move both anchor and loose positions to the new location.
* This may deselect text. In the Windows user-interface, the use of
* the shift key would influence this parameter value.
* @param bLogical - TRUE to perform a logical move; FALSE to perform a
* visual move.
* @return TRUE if the move succeeded; FALSE if not;
*/
public boolean moveChar (boolean bForward, boolean bSelect, boolean bLogical) {
TextPosnBase oPosn = new TextPosnBase (moRange.loose());
boolean bMoved = bForward ? oPosn.nextUserPosn (! bLogical)
: oPosn.prevUserPosn (! bLogical);
moveComplete (oPosn, bSelect);
return bMoved;
}
public boolean moveChar (boolean bForward, boolean bSelect) {
return moveChar (bForward, bSelect, LOGICAL_DEFAULT);
}
/**
* Move ahead/back one word in the underlying text stream.
*
* This corresponds to right and left arrow keys with the ctrl key being
* pressed the in the Windows user-interface.
* @param bForward - (optional) If TRUE (default) move forward one word.
* if FALSE, move back that amount.
* @param bSelect - (optional) If TRUE, start or extend the selection
* represented by this editor. In other words, the range's anchor is
* not changed; its loose end moves ahead/back one word. If FALSE
* (default) move both anchor and loose positions to the new location.
* This may deselect text. In the Windows user-interface, the use of
* the shift key would influence this parameter value.
* @param bLogical - TRUE to perform a logical move; FALSE to perform a
* visual move.
* @param eWordMode - Word positioning mode (see the enumeration
* described in class {@link TextPosnBase}).
* @return TRUE if the move succeeded; FALSE if not;
*/
public boolean moveWord (boolean bForward, boolean bSelect, boolean bLogical, int eWordMode) {
TextPosnBase oPosn = new TextPosnBase (moRange.loose());
boolean bMoved = bForward ? oPosn.nextWord (! bLogical, eWordMode)
: oPosn.prevWord (! bLogical, eWordMode);
moveComplete (oPosn, bSelect);
return bMoved;
}
public boolean moveWord (boolean bForward, boolean bSelect, int eWordMode) {
return moveWord (bForward, bSelect, LOGICAL_DEFAULT, eWordMode);
}
/**
* Move ahead/back one line in the underlying text stream.
*
* This corresponds to the down and up arrow keys in the Windows
* user-interface.
* @param bForward - (optional) If TRUE (default) move forward one line.
* if FALSE, move back that amount.
* @param bSelect - (optional) If TRUE, start or extend the selection
* represented by this editor. In other words, the range's anchor is
* not changed; its loose end moves ahead/back one line. If FALSE
* (default) move both anchor and loose positions to the new location.
* This may deselect text. In the Windows user-interface, the use of
* the shift key would influence this parameter value.
* @return TRUE if the move succeeded; FALSE if not;
*/
public boolean moveLine (boolean bForward, boolean bSelect) {
TextPosnBase oPosn = new TextPosnBase (moRange.loose());
boolean bMoved = false;
if (bForward) {
bMoved = oPosn.down();
if ((! bMoved) && bSelect) {
bMoved = oPosn.end();
}
} else {
bMoved = oPosn.up();
if ((! bMoved) && bSelect) {
bMoved = oPosn.start();
}
}
moveComplete (oPosn, bSelect);
return bMoved;
}
/**
* Move ahead/back one paragraph in the underlying text stream.
*
* There is no corresponding keyboard action in the Windows
* user-interface.
* @param bForward - (optional) If TRUE (default) move forward one paragraph.
* if FALSE, move back that amount.
* @param bSelect - (optional) If TRUE, start or extend the selection
* represented by this editor. In other words, the range's anchor is
* not changed; its loose end moves ahead/back one paragraph. If FALSE
* (default) move both anchor and loose positions to the new location.
* This may deselect text. In the Windows user-interface, the use of
* the shift key would influence this parameter value.
* @return TRUE if the move succeeded; FALSE if not;
*/
public boolean movePara (boolean bForward, boolean bSelect) {
TextPosnBase oPosn = new TextPosnBase (moRange.loose());
boolean bMoved = bForward ? oPosn.nextPara()
: oPosn.prevPara();
moveComplete (oPosn, bSelect);
return bMoved;
}
/**
* Move to start/end of line/text.
*
* This corresponds to the home and end keys (with optional ctrl key) in
* the Windows user-interface.
* @param bAbsolute - (optional) If TRUE (default) move to the start or
* end of the text. If FALSE, move to the start or end of the current
* line.
* @param bForward - (optional) If TRUE (default) move to the end of the
* line/text. if FALSE, move to the start of the line/text.
* @param bSelect - (optional) If TRUE, start or extend the selection
* represented by this editor. In other words, the range's anchor is
* not changed; its loose end moves. If FALSE (default) move both
* anchor and loose positions to the new location. This may deselect
* text. In the Windows user-interface, the use of the shift key would
* influence this parameter value.
* @param bLogical - TRUE to perform a logical move; FALSE to perform a
* visual move.
* @return TRUE if the move succeeded; FALSE if not;
*/
public boolean moveAll (boolean bAbsolute, boolean bForward, boolean bSelect, boolean bLogical) {
TextPosnBase oPosn = new TextPosnBase (moRange.loose());
boolean bMoved = false;
if (bAbsolute) {
if (bForward) {
oPosn.last (! bLogical);
} else {
oPosn.first (! bLogical);
}
bMoved = true; // TBD: can't tell
} else {
if (bForward) {
bMoved = oPosn.end (! bLogical);
} else {
bMoved = oPosn.start (! bLogical);
}
}
moveComplete (oPosn, bSelect);
return bMoved;
}
public boolean moveAll (boolean bAbsolute, boolean bForward, boolean bSelect) {
return moveAll (bAbsolute, bForward, bSelect, LOGICAL_DEFAULT);
}
/*
* Move to a graphic location in the text.
*
* This corresponds to mouse clicking or dragging in the Windows
* user-interface.
* @param oMove - Location, in form coordinates to move to.
* @param bSelect - (optional) If TRUE, start or extend the selection
* represented by this editor. In other words, the range's anchor is
* not changed; its loose end moves to the new location. If FALSE
* (default) move both anchor and loose positions to that location.
* This may deselect text. In the Windows user-interface, the use of
* the shift key would influence this parameter value.
* @param bSelectDescendants (optional) - If TRUE, clicking into a
* descendant stream will update the editor to a position immediately
* before or after the child embedded field that the click occurred in.
* If FALSE, clicking in descendant fields will return failed status and
* the editor does not change.
* @return TRUE if the move succeeded; FALSE if not;
*/
// public boolean MoveTo (CoordPair oMove, boolean bSelect, boolean bSelectDescendants) {
// CoordPair oRelPos = AbsToRel (mpoGfxEnv, oMove);
//
// TextStream poDescendantStream = null;
// TextStream ppoFoundStream = bSelectDescendants ? poDescendantStream : null;
//
// TextPosnBase oPosn = new TextPosnBase (moRange.stream());
// if (oPosn.caretPos (oRelPos, ppoFoundStream)) {
// MoveComplete (oPosn, bSelect, poDescendantStream);
// return true;
// }
//
// return false;
// }
/**
* Extend the editor's range to include complete words.
*
* The start of the editor's range moves back to the start of the word
* containing it. The end of the range moves forward to the end of the
* word that contains it. If either position is not within a word or
* adjacent to one, it does not move.
* @param eWordMode - Word positioning mode (see the enumeration
* described in class {@link TextPosnBase}).
*/
public void grabWord (int eWordMode) {
TextRange oNewRange = new TextRange (moRange);
oNewRange.grabWord();
moveComplete (oNewRange);
}
public void grabWord () {
grabWord (TextPosn.WORD_MODE_LEGACY);
}
/**
* Extend the editor's range to include complete lines.
*
* Note: the associated stream must have a text display for line
* operations to succeed. The start of the editor's range moves back to
* the start of the line containing it. The end of the range moves
* forward to the end of the line that contains it.
*/
public void grabLine () {
TextRange oNewRange = new TextRange (moRange);
oNewRange.grabLine();
moveComplete (oNewRange);
}
/**
* Extend the editor's range to include complete paragraphs.
*
* Note: a paragraph starts after a paragraph mark and runs until just
* after the next paragraph mark. If our range's end position is
* already just beyond a paragraph mark, we normally won't want to move
* it. The exception is when its start is also just after the same mark
* (empty range once tightened). In this case, we maintain the start
* and move the end after the next mark.
*/
public void grabPara () {
TextRange oNewRange = new TextRange (moRange);
oNewRange.grabPara();
moveComplete (oNewRange);
}
/**
* Select the entire text stream.
*
* The editor's range is adjusted to include all content of its
* underlying text stream.
*/
public void grabAll () {
TextRange oNewRange = new TextRange (moRange.stream());
moveComplete (oNewRange);
}
/**
* Count the number of characters currently selected.
* @return Number of characters included in the editor's range. Zero if
* in caret mode.
*/
public int selectCount () {
return moRange.countText();
}
/**
* Obtain the selected (plain) text.
* @return Text string to get a copy of the currently selected
* text.
*/
public String selectText () {
return moRange.text();
}
/**
* Obtain the selected (rich) text.
*
* Copy the content of the editor's range to another stream, replacing
* its previous content. The destination stream retains its graphic
* source, which may be different from that of the associated stream.
* All graphics objects copied are reconciled in the destination
* stream's graphic source. Because this is a copy, the destination
* stream will get clones of any embedded objects or fields.
* @param oSelect - Destination text stream. Not modified if the
* editor's range has no stream association.
*/
public void selectText (TextStream oSelect) {
moRange.text (oSelect);
}
/*
* Obtain the graphic starting point of the selection.
* @param oStart - Returned coordinate pair, in form units, of the top
* left corner of the first selected character. Top left corner of the
* caret if in caret mode.
*/
// public void selectStart (CoordPair oStart) {
// Rect oCaret;
// moRange.start().caretPos (oCaret);
// oStart = oCaret.topLeft();
// }
/*
* Obtain the graphic end point of the selection.
* @param oStart - Returned coordinate pair, in form units, of the
* bottom right corner of the last selected character. Bottom right
* corner of the caret if in caret mode.
*/
// public void selectEnd (CoordPair oEnd) {
// Rect oCaret;
// moRange.end().caretPos (oCaret);
// oEnd = oCaret.bottomRight();
// }
/**
* Obtain the attributes in effect.
*
* Returns a text attribute structure describing the attributes over the
* range or at the current caret position. Any attribute that remains
* constant over the range will have an enabled value in the result.
* Any attribute that changes over the range will be disabled in the
* result.
* @return Text attribute object describing the attributes in
* effect over the range.
*/
public TextAttr attributeGet () {
return moRange.attribute();
}
/**
* Change text attributes.
*
* Given a text attribute object, this method applies enabled attributes
* over the editor's range if in selection mode, or at the current
* position if in caret mode. Note: changing attributes in caret mode
* effectively changes them for a zero-length range surrounding the
* current caret location. If the next operation is a text insertion at
* this location, that text will inherit the new attributes. Otherwise,
* the stream will eventually see the attribute change as redundant and
* discard it. Disabled attributes in the given object are not changed.
* @param oNewAttr - Attribute object with enabled attributes to apply.
*/
public void attributeSet (TextAttr oNewAttr) {
editStart();
moRange.attribute (oNewAttr);
editComplete (true);
}
/**
* Insert or replace the selection with a single character.
*
* This method is analogous to typing a single character. If there is a
* selection, it is first deleted. Then, the given character is
* inserted. Upon return, the editor is in caret mode, positioned after
* the newly inserted character.
* @param cInsert - Character to insert.
*/
public void replace (char cInsert, boolean bKeepRange) {
editStart();
moRange.replace (cInsert);
editComplete (bKeepRange);
}
/**
* Insert or replace the selection with text.
*
* This method is analogous to pasting plain text from the clipboard.
* If there is a selection, it is first deleted. Then, the given text
* is inserted. Upon return, the editor is in caret mode, positioned
* after the newly inserted text.
* @param sInsert - Text to insert.
*/
public void replace (String sInsert, boolean bKeepRange) {
editStart();
moRange.replace (sInsert);
editComplete (bKeepRange);
}
/**
* Insert or replace the selection with rich text.
*
* This method is analogous to pasting rich text from the clipboard. If
* there is a selection, it is first deleted. Then, the given text is
* inserted. Upon return, the editor is in caret mode, positioned after
* the newly inserted text.
* @param oInsert - Text to insert.
*/
public void replace (TextStream oInsert, boolean bKeepRange) {
editStart();
moRange.replace (oInsert);
editComplete (bKeepRange);
}
/**
* Insert or replace the selection with a paragraph mark.
*
* This method is analogous to pressing the enter key in an application
* that supports paragraphs. If there is a selection, it is first
* deleted. Then, the paragraph mark is inserted. Upon return, the
* editor is in caret mode, positioned after the newly inserted
* paragraph mark.
*/
public void replacePara () {
editStart();
moRange.delete();
TextPosnBase oPosn = new TextPosnBase (moRange.anchor());
oPosn.insertPara();
editComplete();
}
/**
* Delete one characer.
*
* Delete one character at the "loose" end of the range.
* @param bForward - TRUE to delete the character immediately after the
* loose end of the range; FALSE to delete the character immediately
* before it.
*/
public void deleteChar (boolean bForward) {
editStart();
TextPosnBase oPosn = new TextPosnBase (moRange.loose());
if (bForward) {
oPosn.deleteAhead();
} else {
oPosn.deleteBack();
}
editComplete();
}
/**
* Delete the current word(s).
*
* Extend the caret position or current selection to select complete
* words (see GrabWord() above and then delete the selection. On
* return, the editor will be in caret mode at the point of deletion.
* @param bForward - Currently ignored.
* @param eWordMode - Word positioning mode (see the enumeration
* described in class {@link TextPosnBase}).
*/
public void deleteWord (boolean bForward, int eWordMode) {
grabWord();
deleteSelect();
}
public void deleteWord (boolean bForward) {
deleteWord (bForward, TextPosn.WORD_MODE_LEGACY);
}
/**
* Delete the current line(s).
*
* Extend the caret position or current selection to select complete
* lines (see GrabLine() above and then delete the selection. On
* return, the editor will be in caret mode at the point of deletion.
* @param bForward - Currently ignored.
*/
public void deleteLine (boolean bForward) {
grabLine();
deleteSelect();
}
/**
* Delete the current paragraph(s).
*
* Extend the caret position or current selection to select complete
* paragraphs (see GrabPara() above and then delete the selection. On
* return, the editor will be in caret mode at the point of deletion.
* @param bForward - Currently ignored.
*/
public void deletePara (boolean bForward) {
grabPara();
deleteSelect();
}
/**
* Delete the entire stream content.
*
* Implicitly select the entire stream and then delete it. On return,
* the editor will be in caret mode in an empty stream.
* @param bForward - Currently ignored.
*/
public void deleteAll (boolean bForward) {
grabAll();
deleteSelect();
}
/**
* Delete the current selection.
*
* Delete the selected text. If the editor is currently in caret mode,
* the call is ignored.
*/
public void deleteSelect () {
editStart();
moRange.delete();
editComplete();
}
/**
* Call-back: Create a duplicate of this editor.
*
* Create a duplicate of this object. The derived class should create a
* new object of its own type and copy all additional data that it
* carries, including base class copy. The default implementation
* creates a TextEditor and copies stream association and graphic
* environment.
* @return Pointer to cloned copy.
*/
public TextEditor cloneEditor () {
return new TextEditor (this);
}
/**
* Call-back: Text content change notification.
*
* The editor calls this method after any operation changes the
* underlying text stream. The default implementation notifies the text
* display of the change, and should be called by any overriding
* implementation.
* @param bExtentChanged - TRUE if the extent of the text has changed;
* FALSE if not.
*/
public void onTextChanged (boolean bExtentChanged) {
// if (Display() != null) {
// Display().onChange (bExtentChanged);
// }
}
/**
* Call-back: Relative to absolute coordinate conversion.
*
* The text editor works entirely in local text display stream
* coordinates (e.g., (0,0) is the top left corner if the text object).
* This method allows the derived class to convert local text
* coordinates to more global form coordinates.
* @param poGfxEnv - Graphic environment in which the conversion must
* occur.
* @param oPoint - The editor calls this method with the local point to
* convert; the derived class replaces its value with the converted
* point. The default implementation does nothing to the point.
*/
public CoordPair relToAbs (GFXEnv poGfxEnv, CoordPair oPoint) {
// GFXScrollingEnv poScrollingEnv = ScrollingEnv (poGfxEnv);
// if (poScrollingEnv != null) {
// oPoint += poScrollingEnv.offset();
// }
return oPoint;
}
/**
* Call-back: Absolute to relative coordinate conversion.
*
* The text editor works entirely in local text display stream
* coordinates (e.g., (0,0) is the top left corner if the text object).
* This method allows the derived class to convert global form
* coordinates to local text coordinates.
* @param poGfxEnv - Graphic environment in which the conversion must
* occur.
* @param oPoint - The editor calls this method with the global point to
* convert; the derived class replaces its value with the converted
* point. The default implementation does nothing to the point.
*/
public CoordPair absToRel (GFXEnv poGfxEnv, CoordPair oPoint) {
// GFXScrollingEnv poScrollingEnv = ScrollingEnv (poGfxEnv);
// if (poScrollingEnv != null) {
// oPoint -= poScrollingEnv.offset();
// }
return oPoint;
}
/*
* Call-back: Obtain the current caret rotation angle.
*
* The local coordinate system used by AXTE works in a non-rotated
* space. This method returns the current caret rotation angle.
* @return Current rotation angle. The default implementation always
* returns zero.
*/
// public Angle caretRotation () {
// static Angle oDefault;
// return oDefault;
// }
/**
* Call-back: Show/hide the caret.
*
* The editor calls this method after any operation that may change the
* appearance of the caret. For example, going from caret mode to a
* selection requires that the caret be hidden. An application with
* special caret handling needs might want to override this method.
* However, the default implementation is reasonably rich: it uses the
* Gfx package to show/hide the caret depending on selection or caret
* mode, and will display the caret properly rotated for the four basic
* angles. If the application overrides ShowCaret(), it may still want
* to call the base class implementation.
*/
public void showCaret () {
// if ((! mbUpdateDisplay) || (mpoGfxEnv == null)) {
// return;
// }
//
// TextDisplay poDisplay = Display();
// if (poDisplay == null) {
// return;
// }
//
// if (! moRange.isEmpty()) {
// mpoGfxEnv.windowCaretHide();
// moRange.loose().scrollTo (mpoGfxEnv);
// }
//
// else {
// Rect oCaretRect;
// CoordPair oCaretPos;
// moRange.anchor().caretPos (oCaretRect);
//
// Angle oAngle = CaretRotation();
// long lAngle = oAngle.degrees();
//
// if (lAngle != 0) {
// oCaretRect.rotate (CoordPair(), oAngle);
//
//// move the left side to the right.
// if (lAngle <= 45 || lAngle >= 315) {
// CoordPair o (oCaretRect.right(), oCaretRect.top());
// oCaretRect.topLeft (o);
// }
//// move the bottom side up to the top.
// else if (lAngle < 135) {
// CoordPair o (oCaretRect.right(), oCaretRect.top());
// oCaretRect.bottomRight (o);
// }
//// move the right side to the left.
// else if (lAngle <= 225) {
// CoordPair o (oCaretRect.left(), oCaretRect.bottom());
// oCaretRect.bottomRight (o);
// }
//// move the top side down to the bottom.
// else if (lAngle < 315) {
// CoordPair o (oCaretRect.left(), oCaretRect.bottom());
// oCaretRect.topLeft (o);
// }
// }
//
// moRange.loose().scrollTo (mpoGfxEnv);
//
// oCaretPos = oCaretRect.topLeft();
// RelToAbs (mpoGfxEnv, oCaretPos);
// mpoGfxEnv.windowCaretSize (oCaretRect.width(), oCaretRect.height());
// mpoGfxEnv.windowCaretMove (oCaretPos);
// mpoGfxEnv.windowCaretShow();
// }
}
// purpose unknown; not called by editor
public void complete () {
moRange.start (moRange.end());
}
private void moveComplete (TextPosnBase oPosn, boolean bSelect, TextStream poDescendantStream) {
TextRange oNewRange = new TextRange (moRange);
oNewRange.loose (oPosn.index());
if (! bSelect) {
TextPosnBase oStart = new TextPosnBase (oPosn);
if ((poDescendantStream != null)
&& (poDescendantStream != moRange.stream())) { // if selected in descendant stream ...
oStart.prev(); // ... select entire item
}
oNewRange.anchor (oStart.index());
}
moveComplete (oNewRange);
}
private void moveComplete (TextPosnBase oPosn, boolean bSelect) {
moveComplete (oPosn, bSelect, null);
}
private void moveComplete (TextRange oNewRange) { // takes ownership of oNewRange
oNewRange.tighten(); // exclude attribute changes
if (mbUpdateDisplay && (mpoGfxEnv != null)) {
TextDisplay poDisplay = display();
if (poDisplay != null) {
// poDisplay.updateSelected (mpoGfxEnv, moRange, oNewRange, false);
}
}
moRange = oNewRange;
// moRange.loose().setKeyboard();
showCaret();
}
private void editStart () {
moRange.tighten();
Rect poExtent = extent();
if (poExtent != null) {
moPrevExtent = poExtent;
}
}
private void editComplete (boolean bKeepRange) {
if (! bKeepRange) {
moRange.start (moRange.end());
}
boolean bExtentChange = false;
Rect poExtent = extent();
if ((poExtent != null) && (poExtent != moPrevExtent)) {
bExtentChange = true;
}
onTextChanged (bExtentChange);
showCaret();
}
private void editComplete () {
editComplete (false);
}
private Rect extent () {
//TextDisplay poDisplay = display();
// if (poDisplay == NULL)
return null;
// else
// return poDisplay->Extent(); // TBD: figure this out with frames
}
private TextDisplay display () {
TextStream poStream = moRange.stream();
if (poStream == null) {
return null;
}
return poStream.display();
}
// private GFXScrollingEnv scrollingEnv (GFXEnv poGfxEnv) {
// TextDisplay poDisplay = Display();
// if (poDisplay == null) {
// return null;
// }
//
// TextScroller poScroller = poDisplay.textConnect().scroller();
// if (poScroller == null) {
// return null;
// }
//
// return poScroller.scrollingEnv (poGfxEnv);
// }
private static int userIndexToStreamIndex (TextStream poStream, int nUserIndex) {
TextPosnBase oPosn = new TextPosnBase (poStream);
if (nUserIndex > poStream.posnCount()) {
nUserIndex = poStream.posnCount();
}
while (nUserIndex-- > 0) {
oPosn.nextUserPosn();
}
return oPosn.index();
}
private static int streamIndexToUserIndex (TextStream poStream, int nStreamIndex) {
TextPosnBase oPosn = new TextPosnBase (poStream, nStreamIndex);
int nUserIndex = 0;
while (oPosn.prevUserPosnType() != TextItem.UNKNOWN) {
nUserIndex++;
}
return nUserIndex;
}
}