All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.xfa.text.TextEditor Maven / Gradle / Ivy

There is a newer version: 2024.11.18598.20241113T125352Z-241000
Show newest version
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; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy