|
|
|
|
||
|
DEFINITION MODULE DMTextFields; (******************************************************************* Module DMTextFields ('Dialog Machine' DM_V3.0) Copyright (c) 1989-2006 by Andreas Fischlin and ETH Zurich. Purpose Extension of DMEditFields. This module provides the needed operations to make an ordinary text field as installed by DMEditFields to behave like a full blown text editor. Remarks Implementation restriction: Only texts to a maximum size of 32000 characters (ca. 32KBytes) can be edited in a single text field. However, there can be any number of text fields. This module belongs to the 'Dialog Machine'. Programming o Design Andreas Fischlin 07/12/1989 o Implementation Andreas Fischlin 07/12/1989 ETH Zurich Systems Ecology CHN E 35.1 Universitaetstrasse 16 8092 Zurich SWITZERLAND URLs: <mailto:RAMSES@env.ethz.ch> <http://www.sysecol.ethz.ch> <http://www.sysecol.ethz.ch/SimSoftware/RAMSES> Last revision of definition: 31/01/1990 AF *******************************************************************) FROM DMWindows IMPORT WindowFrame; FROM DMEditFields IMPORT EditItem; TYPE TextPointer = POINTER TO TextSegment; TextSegment = ARRAY [0..32000] OF CHAR; PROCEDURE RedefineTextField(textField: EditItem; wf: WindowFrame; withFrame: BOOLEAN); (* Redefines the outer dimensions and position as given by wf of the text field textField requiring a previous installation of the text field via the procedure DMEditFields.TextField. It also allows to suppress the frame, which, by default, is drawn around a text field. Note that eventually attached scroll bars will also be resized according to the new sizes. Typically you call this procedure to hide the frame, when you wan't to program an actual text editor and from within the redefine mouse handler as installed in DMMaster. *) PROCEDURE CopyWTextIntoTextField (textField: EditItem; VAR done: BOOLEAN); PROCEDURE CopyTextFromFieldToWText (textField: EditItem); (* Transfers the textual content of the text field textField back and forth between the so-called window text of the window to which the text field belongs; the window text is a textual data structure associated with a particular window (at a time one such data structure per window only) and if the window is the current output window. See also routines from module DMWTextIO or PrintText from DMPrinting. Text objects can be of any size as long as there is enough memory available; however, text fields can hold only a TextSegment, i.e. a string of length <= 32000. CopyWTextIntoTextField returns false if the window text exceeds this limit. *) PROCEDURE SetSelection(textField: EditItem; beforeCh,afterCh: INTEGER); PROCEDURE GetSelection (textField: EditItem; VAR beforeCh,afterCh: INTEGER); (* Sets or returns the current selection in the text of a text field. The current selection is automatically made visible in the text field via inversion. All characters are numbered according to their position in a TextSegment. beforeCh and afterCh denote the index of the first respectively the last character in the selection. If beforeCh and afterCh have the same value, the selection represents the so-called insertion point, denoting that if the user presses keys, these characters will be inserted in the text segment before the character beforeCh, i.e. the first typed character will become text[beforeCh], the next text[beforeCh+1] etc. Note that the old text[beforeCh] will be automatically shifted to the next higher, available position. Setting the selection outside the currently visible lines will automatically scroll the text, so that the selection becomes visible. All these activities will be automatically taken care of by the Dialog Machine. *) PROCEDURE GetSelectedChars(textField: EditItem; VAR text: ARRAY OF CHAR); (* Copies the currently selected chars into text *) PROCEDURE DeleteSelection(textField: EditItem); (* Deletes currently selected chars *) PROCEDURE InsertBeforeCh(textField: EditItem; VAR text: ARRAY OF CHAR; beforeCh: INTEGER); (* Inserts the text text in the text field textField before the character beforeCh, shifting all characters at positions >= beforeCh to the next higher available positions. *) PROCEDURE GetTextSizes(textField: EditItem; VAR curTextLength, nrLns, charHeight, firstLnVis, lastLnVis: INTEGER); (* Returns several properties of the text currently contained in the text field ei, where - curTextLength Number of characters in text - nrLns Number of lines in the text - charHeight Height of a character or a line in pixels - firstLnVis Ordinal number of first visible line (if text has been scrolled, this number is different from 1, the very first line of the text) - lastLnVis Ordinal number of last visible line (number of currently visible lines = lastLnVis-firstLnVis+1 ) *) PROCEDURE WrapText (textField: EditItem; wrap: BOOLEAN); (* Sets the mode in which text is displayed, i.e. if wrap is true the portions of lines longer than what can be currently displayed in the text field are wrapped onto the next line. If wrap is false, line contents are always displayed on just one line regardless of their length. *) PROCEDURE GrabText(textField: EditItem; VAR txtbeg: TextPointer; VAR curTextLength: INTEGER); (* Makes the text contained in the text field available for inspection at memory location starting with address txtbeg without having to make a copy of it by calling procedure GetText (also from this module). Since the text is internally contained in a so-called handle, it can move in memory, which would make the access dangerous, unless it is temporarily locked to a particular position. This procedure does exactly do this (calls HLock of the memory manager) and hence, it is very important to release the text with procedure ReleaseText once you are through with the inspection of the text. WARNING: Never forget to call ReleaseText after a call to GrabText or the normal editing process in the text field might no longer function properly. *) PROCEDURE ReleaseText(textField: EditItem); (* Relases the text from a particular memory location after a call to procedure GrabText *) PROCEDURE FindInText(textField: EditItem; stringToFind: ARRAY OF CHAR; VAR firstCh,lastCh: INTEGER): BOOLEAN; (* Predefined pattern matching alogorithm to find in the text of the text field textField the string stringToFind starting with the search from the current position as given by the current selection. If it finds the string the algorithm returns TRUE and returns the position of the found string in the values of firstCh and lastCh according to the rules as valid for a selection. If it can't find the sring, the values in firstCh and lastCh represent those of the current selection and FALSE is returned. The implementation of this procedure is: PROCEDURE FindInText(textField: EditItem; stringToFind: ARRAY OF CHAR; VAR firstCh,lastCh: INTEGER): BOOLEAN; VAR searched,ch: CHAR; i,j,lasti,len,startPos: INTEGER; theText: TextPointer; BEGIN GrabText(textField,theText,lasti); len:=Length(stringToFind); DEC(lasti,len); (* start with search after selection otherwise begin with current insertion point: *) GetSelection(textField,firstCh,lastCh); IF firstCh<>lastCh THEN startPos := lastCh+1 ELSE startPos := firstCh END; IF (startPos > lasti) OR (len = 0) THEN (* no search possible *) ReleaseText(textField); RETURN FALSE ELSE (* search is possible *) i:= startPos; WHILE i<=lasti DO j:= 0; (* index in 'stringToFind' *) REPEAT searched:= stringToFind[j]; ch := theText^[i+j]; INC(j); UNTIL (ch # searched) OR (j=len); IF (ch # searched) THEN (* start with next position *) INC(i); ELSE (* position found *) firstCh := i; lastCh := firstCh+len-1; ReleaseText(textField); RETURN TRUE END(*IF*); END(*WHILE*); ReleaseText(textField); RETURN FALSE END(*IF*); END FindInText; Feel free to write and use your own. *) PROCEDURE ScrollText(textField: EditItem; dcols,dlines: INTEGER); (* Scrolls the text by dcols columns and dlines lines. If a scroll bar is attached to the text field, the corresponding position of the scroll box will be set. Positive dlines will scroll the text up, negatives down; positive dcols will scroll the text to the right, negative ones to the left *) PROCEDURE ScrollTextWithWindowScrollBars(textField: EditItem); PROCEDURE AddScrollBarsToText(textField: EditItem; withVerticalScrollBar, withHorizontalScrollBar: BOOLEAN); (* Above two procedures associate a scroll bar with the text content of the text field textField. The vertical sroll bar will be shown at the right of the text field, the horizontal below the text field. The procedure ScrollTextWithWindowScrollBars uses the scroll bars of the Dialog Machine window (see DMWindows) and does not attach additional scroll bars to the text field. If they are missing in the window of the text field, no action takes place and EditFieldsDone becomes FALSE. Once called, the effect of these procedures will be that all scrolling of the text in the text field will be taken care of by the Dialog Machine. In particular this is valid for all scrolling by the user via the scroll bars (page up/down, line up/down, scroll box) and by clicking the mouse in the middle of a text field and moving it outside of the field while still holding down the mouse button (so-called auto scrolling), via text insertion or cutting/deletion, as well as via moving the selection (see SetSelection) outside of the currently visible portion of the text. *) END DMTextFields.
|
||
|
|
|