ETHZ_Logo RAMSES_Logo_Right   RAMSES   RAMSES_Logo_Left Systems Ecology  
Start    search button      Modules:   A-Z   Function   Layer        QuickRefs:   DM   AuxLib   AuxLibE   SciLib   EasyMW   MW   ISIS   RMSLib

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.

  Contact RAMSES@env.ethz.ch Last updated: 25-Jul-2011 [Top of page]