| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- IMPLEMENTATION MODULE StrInput;
- (*
- * REPERTOIRE
- * Release 1.6
- * By Charles Bradford and Cole Brecheen
- * (c) Copyright 1985-1992 PMI
- * Green Bay, Wisconsin
- * All rights reserved
- * (414) 468-6040
- *
- * $Header: D:/logfiles/mods/strinput.mov 1.7 10 Mar 1991 15:33:36 coleb $
- *
- *)
- (*EntryDiag:
- IMPORT Diagnostics;
- :EntryDiag*)
- IMPORT BigSets;
- IMPORT ErrorManager;
- IMPORT KbdInput;
- IMPORT Key;
- IMPORT LowLevel;
- IMPORT M2Strings;
- IMPORT Numbers;
- IMPORT PosUtils;
- IMPORT Spkr;
- IMPORT StrConv;
- IMPORT StrEdit;
- IMPORT SYSTEM;
- IMPORT VWindows;
- VAR
- Initialized : BOOLEAN;
- PROCEDURE Init();
- BEGIN
- IF Initialized THEN
- RETURN;
- ELSE
- Initialized := TRUE;
- END;
- (*EntryDiag:
- Diagnostics.Init();
- :EntryDiag*)
- BigSets.Init();
- ErrorManager.Init();
- KbdInput.Init();
- Key.Init();
- LowLevel.Init();
- M2Strings.Init();
- Numbers.Init();
- PosUtils.Init();
- Spkr.Init();
- StrConv.Init();
- StrEdit.Init();
- VWindows.Init();
- (*EntryDiag:
- Diagnostics.diagS( 'Entering StrInput', '' );
- :EntryDiag*)
- BeepAtNumbers := TRUE;
- (*EntryDiag:
- Diagnostics.diagS( 'Exiting StrInput', '' );
- :EntryDiag*)
- END Init;
- CONST
- Minus = 45; (* ORD('-') *)
- DecimalKey = 46; (* ORD('.') *)
- CurrencySymbol = '$';
- blank = ' ';
- PROCEDURE ReadWithEdits( WindowHandle: VWindows.AWindowHandle;
- VAR TheStr : ARRAY OF CHAR; col1, row1, FieldWidth:
- CARDINAL; VAR CursorPos: CARDINAL; VAR InsertMode: BOOLEAN;
- scrolling: BOOLEAN; VAR LastKey : CARDINAL; VAR LegalKeys,
- ExitKeys : KbdInput.KeyNumSet );
- VAR
- bufch : CHAR;
- done, RedrawNeeded : BOOLEAN;
- SavedHeight, StrNdx, CharsScrolled, TheStrLen : CARDINAL;
- AllOkKeys: KbdInput.KeyNumSet;
- (* CursorPos = current offset of cursor from start of field *)
- PROCEDURE redraw( BeginningAt: CARDINAL );
- VAR
- TmpStr: ARRAY [0..79] OF CHAR;
- BEGIN
- IF (BeginningAt < CharsScrolled) THEN
- HALT();
- END;
- M2Strings.Copy( TheStr, BeginningAt,
- M2Strings.Length(TheStr) - BeginningAt, TmpStr );
- BeginningAt := BeginningAt - CharsScrolled;
- StrEdit.SetLength( TmpStr, FieldWidth - BeginningAt );
- IF (BeginningAt < FieldWidth) THEN
- VWindows.DrawStr( WindowHandle, col1 + BeginningAt,
- row1, SYSTEM.ADR(TmpStr), FieldWidth - BeginningAt );
- RedrawNeeded := FALSE;
- END;
- END redraw;
- PROCEDURE MoveToPos( StrOffset: CARDINAL );
- BEGIN
- WHILE (CursorPos + CharsScrolled) > StrOffset DO
- (* we are moving backwards *)
- IF CursorPos > 0 THEN
- DEC( CursorPos );
- ELSE
- RedrawNeeded := TRUE;
- DEC( CharsScrolled );
- END;
- DEC( StrNdx );
- END;
- WHILE (CursorPos + CharsScrolled) < StrOffset DO
- (* we are moving forewards *)
- IF CursorPos < FieldWidth THEN
- INC( CursorPos );
- ELSE
- RedrawNeeded := TRUE;
- INC( CharsScrolled );
- END;
- INC( StrNdx );
- END;
- END MoveToPos;
- PROCEDURE LeftToChar( TheChar: CHAR );
- BEGIN
- WHILE (StrNdx > 0) AND (TheStr[ StrNdx ] # TheChar) DO
- MoveToPos( StrNdx - 1 );
- END;
- END LeftToChar;
- PROCEDURE RightToChar( TheChar: CHAR );
- BEGIN
- WHILE (StrNdx < TheStrLen) AND (TheStr[ StrNdx ] # TheChar) DO
- MoveToPos( StrNdx + 1 );
- END;
- END RightToChar;
- PROCEDURE SkipLeftOver( TheChar: CHAR );
- BEGIN
- WHILE (StrNdx > 0) AND (TheStr[ StrNdx ] = TheChar) DO
- MoveToPos( StrNdx - 1 );
- END;
- END SkipLeftOver;
- PROCEDURE SkipRightOver( TheChar: CHAR );
- BEGIN
- WHILE (StrNdx < TheStrLen) AND (TheStr[ StrNdx ] = TheChar) DO
- MoveToPos( StrNdx + 1 );
- END;
- END SkipRightOver;
- BEGIN
- (* ReadWithEdits *)
- SavedHeight := VWindows.GetCursorHeight(WindowHandle);
- TheStrLen := M2Strings.Length( TheStr );
- BigSets.SetUnion( LegalKeys, ExitKeys, AllOkKeys);
- FieldWidth := Numbers.Min( HIGH(TheStr) + 1, FieldWidth );
- IF FieldWidth = 0 THEN
- (* This means you can pass 0 to FieldWidth if your only
- width concern is preventing overflow of TheStr. *)
- FieldWidth := HIGH( TheStr ) + 1;
- IF FieldWidth > (VWindows.EndCol(WindowHandle) - col1) THEN
- FieldWidth := VWindows.EndCol(WindowHandle) - col1;
- END;
- END;
- WHILE TheStrLen < FieldWidth DO
- StrEdit.Append( TheStr, blank );
- INC( TheStrLen );
- END;
- IF (NOT scrolling) AND (TheStrLen > FieldWidth) THEN
- StrEdit.SetLength( TheStr, FieldWidth );
- TheStrLen := FieldWidth;
- END;
- CharsScrolled := 0;
- StrNdx := CursorPos;
- VWindows.GotoXY( WindowHandle, col1 + CursorPos, row1);
- IF InsertMode THEN
- VWindows.SetCursorHeight( WindowHandle, 6 )
- ELSE
- VWindows.SetCursorHeight( WindowHandle, 2);
- END;
- (*turns on cursor*)
- done := FALSE;
- RedrawNeeded := TRUE;
- REPEAT
- IF RedrawNeeded THEN
- redraw( CharsScrolled );
- END;
- VWindows.GotoXY( WindowHandle, col1 + CursorPos, row1);
- LastKey := KbdInput.KeyHit( AllOkKeys);
- CASE LastKey OF
- Key.Left : (* move to prior character position *)
- IF StrNdx > 0 THEN
- MoveToPos( StrNdx - 1 );
- ELSE
- IF BigSets.InSet( ExitKeys, LastKey ) THEN
- (* left arrow at start moves to prior field if
- Key.Left in ExitKeys *)
- done := TRUE;
- END;
- END;
- | Key.Right : (* move to next character position *)
- IF StrNdx + 1 < TheStrLen THEN
- MoveToPos( StrNdx + 1 );
- ELSE
- IF BigSets.InSet( ExitKeys, LastKey ) THEN
- (* left arrow at end moves to next field if
- Key.Right in ExitKeys *)
- done := TRUE;
- END;
- END;
- | Key.Del : (* Delete char under cursor *)
- M2Strings.Delete( TheStr, StrNdx, 1 );
- StrEdit.Append( TheStr, blank );
- redraw( StrNdx );
- | Key.Home : (* Go to beginning of field *)
- IF BigSets.InSet( ExitKeys, LastKey ) THEN
- done := TRUE;
- ELSE
- MoveToPos( 0 );
- END;
- | Key.End : (* Go past last character written *)
- IF BigSets.InSet( ExitKeys, LastKey ) THEN
- done := TRUE;
- ELSE
- MoveToPos( TheStrLen - 1 );
- SkipLeftOver( blank );
- RightToChar( blank );
- END;
- | Key.CtrlRight, Key.Tab : (* Go to next word *)
- IF ((StrNdx = TheStrLen) OR (LastKey = Key.Tab)) AND
- BigSets.InSet( ExitKeys, LastKey ) THEN
- (* Tab or no next word found, so exit *)
- done := TRUE;
- ELSE
- IF TheStr[ StrNdx ] = blank THEN
- SkipRightOver( blank );
- ELSE
- RightToChar( blank );
- SkipRightOver( blank );
- END;
- END;
- | Key.CtrlLeft, Key.BackTab : (* Go to previous word *)
- IF ((StrNdx = 0) OR (LastKey = Key.BackTab)) AND BigSets.InSet(
- ExitKeys, LastKey ) THEN
- (* BackTab or no previous word, so exit *)
- done := TRUE;
- ELSE
- IF TheStr[ StrNdx ] # blank THEN
- LeftToChar( blank );
- END;
- SkipLeftOver( blank );
- LeftToChar( blank );
- SkipRightOver( blank );
- END;
- | Key.AltD : (* Erase the entire entry *)
- LowLevel.Fill( SYSTEM.ADR( TheStr ), TheStrLen, blank );
- MoveToPos( 0 );
- RedrawNeeded := TRUE;
- | Key.AltE : (* Erase to the end of the field *)
- LowLevel.Fill( LowLevel.AddAddr( SYSTEM.ADR(TheStr),
- StrNdx), TheStrLen - StrNdx, blank );
- redraw( StrNdx );
- | Key.Ins : (* Toggle insert mode on and off *)
- InsertMode := NOT InsertMode;
- IF InsertMode THEN
- VWindows.SetCursorHeight( WindowHandle, 6 )
- ELSE
- VWindows.SetCursorHeight(WindowHandle, 2);
- END;
- | Key.Escape :
- done := TRUE;
- (* Unconditionally exit if the user presses ESC. *)
- | Key.BackSpace :
- IF (StrNdx > 0) THEN
- MoveToPos( StrNdx - 1 );
- IF InsertMode THEN
- M2Strings.Delete( TheStr, StrNdx, 1 );
- StrEdit.Append( TheStr, blank );
- ELSE
- TheStr[ StrNdx ] := blank;
- END;
- redraw( StrNdx );
- ELSIF BigSets.InSet( ExitKeys, LastKey ) THEN
- done := TRUE;
- END;
- ELSE
- IF BigSets.InSet( ExitKeys, LastKey ) THEN
- done := TRUE;
- ELSIF (StrNdx < TheStrLen) AND (LastKey <
- KbdInput.Extended) THEN
- (* normal key pressed and cursor is not past end *)
- IF InsertMode THEN
- IF NOT scrolling THEN
- M2Strings.Delete( TheStr, TheStrLen - 1, 1 );
- END;
- bufch := CHR( LastKey );
- M2Strings.Insert( bufch, TheStr, StrNdx );
- ELSE
- TheStr[ StrNdx ] := CHR( LastKey );
- END;
- redraw( StrNdx );
- MoveToPos( StrNdx + 1 );
- ELSE
- Spkr.Noise( Spkr.Warble, Spkr.Normal,
- Spkr.Short);
- END;
- END;
- UNTIL done;
- StrEdit.SetLength( TheStr, FieldWidth );
- (*We do this because TheStr may have gotten longer if
- we've been scrolling.*)
- VWindows.SetCursorHeight( WindowHandle, SavedHeight );
- END ReadWithEdits;
- PROCEDURE ReadNumeric( WindowHandle:
- VWindows.AWindowHandle; VAR TheStr : ARRAY OF
- CHAR; col1, row1, FieldWidth: CARDINAL;
- DecimalPlaces: CARDINAL; FloatingPoint: BOOLEAN;
- VAR InDecimals: BOOLEAN; VAR LastKey : CARDINAL;
- VAR ExitKeys : KbdInput.KeyNumSet );
- VAR
- SavedHeight, cnt, DecimalSpot, InsertionPoint,
- NonBlankLength: CARDINAL;
- AtLeadingZero: BOOLEAN;
- LegalKeys, AllOkKeys: KbdInput.KeyNumSet;
- DumStr: ARRAY [0..0] OF CHAR;
- BEGIN
- (* First we make sure the FieldWidth is okay. *)
- IF FieldWidth = 0 THEN
- FieldWidth := HIGH( TheStr ) + 1;
- ELSE
- FieldWidth := Numbers.Min( HIGH(TheStr) + 1, FieldWidth );
- END;
- FieldWidth := Numbers.Min( VWindows.EndCol(WindowHandle) - col1,
- FieldWidth );
- StrEdit.RightJustify( TheStr, FieldWidth );
- SavedHeight := VWindows.GetCursorHeight(WindowHandle);
- VWindows.SetCursorHeight( WindowHandle, 2 );
- (* Now we make sure DecimalPlaces is consistent with
- TheStr; if it's not, the number of DecimalPlaces in
- TheStr overrides. If there's no decimal point in TheStr
- at all, however, we'll make it consistent with
- DecimalPlaces. *)
- IF PosUtils.PresentPos( CHR(DecimalKey), TheStr, DecimalSpot ) THEN
- IF (DecimalSpot + 1) # (FieldWidth - DecimalPlaces) THEN
- DecimalPlaces := (FieldWidth - DecimalSpot) - 1;
- END;
- ELSIF (DecimalPlaces > 0) OR FloatingPoint THEN
- IF DecimalPlaces = 0 THEN
- (*We're here because FloatingPoint was true.*)
- DecimalPlaces := 1;
- (*Makes sure that we've at least got 0.0 in TheStr if
- FloatingPoint is true; prevents InsertionPoint from
- incrementing beyond FieldWidth, below.*)
- END;
- IF PosUtils.IsBlank( TheStr ) THEN
- StrEdit.InsertRightJustified( '0', TheStr, FieldWidth );
- END;
- StrEdit.InsertRightJustified( '.', TheStr, FieldWidth );
- FOR cnt := 1 TO DecimalPlaces DO
- StrEdit.InsertRightJustified( '0', TheStr, FieldWidth );
- END;
- DecimalSpot := PosUtils.Pos( CHR(DecimalKey), TheStr );
- ELSE
- DecimalSpot := M2Strings.Length( TheStr );
- IF PosUtils.IsBlank( TheStr ) THEN
- (* Mike McCarthy's bug fix. *)
- StrEdit.InsertRightJustified( '0', TheStr, FieldWidth );
- END;
- END;
- (* Now force FloatingPoint to false if CurrencySymbol is in
- TheStr. *)
- IF PosUtils.Present( CurrencySymbol, TheStr ) THEN
- FloatingPoint := FALSE;
- END;
- (* Now we find the insertion point. *)
- InsertionPoint := DecimalSpot;
- IF InDecimals THEN
- REPEAT
- INC( InsertionPoint );
- UNTIL (InsertionPoint >= FieldWidth) OR
- (TheStr[InsertionPoint] = '0');
- ELSE
- IF (TheStr[ InsertionPoint - 1 ] = '0') AND ( (InsertionPoint <=
- 1) OR (NOT PosUtils.Present(TheStr[InsertionPoint - 2],
- '0123456789'))) THEN
- AtLeadingZero := TRUE;
- ELSE
- AtLeadingZero := FALSE;
- END;
- END;
- BigSets.InitSet( LegalKeys );
- BigSets.AppendSet( LegalKeys, "{8, 331, '.', '-', '0'..'9'}" );
- BigSets.SetUnion( LegalKeys, ExitKeys, AllOkKeys);
- REPEAT
- VWindows.DrawStr( WindowHandle, col1, row1, SYSTEM.ADR(TheStr), 0 );
- VWindows.GotoXY( WindowHandle, col1 + InsertionPoint, row1 );
- LastKey := KbdInput.KeyHit( AllOkKeys);
- CASE LastKey OF
- 48..57: (* ASCII values of '0' to '9' *)
- IF InDecimals THEN
- IF (InsertionPoint = FieldWidth) THEN
- IF FloatingPoint AND (TheStr[0] = blank) THEN
- DumStr[0] := CHR(LastKey);
- IF BeepAtNumbers THEN
- Spkr.TimedNoise( (LastKey * 100) - 4400, 2 );
- END;
- StrEdit.InsertRightJustified( DumStr, TheStr,
- InsertionPoint );
- DEC( DecimalSpot );
- ELSE
- Spkr.Noise( Spkr.Warble, Spkr.Normal,
- Spkr.Short);
- END;
- ELSE
- IF BeepAtNumbers THEN
- Spkr.TimedNoise( (LastKey * 100) - 4400, 2 );
- END;
- TheStr[ InsertionPoint ] := CHR( LastKey );
- INC( InsertionPoint );
- END;
- ELSE
- IF AtLeadingZero THEN
- IF CHR(LastKey) # '0' THEN
- IF BeepAtNumbers THEN
- Spkr.TimedNoise( (LastKey * 100) - 4400, 2 );
- END;
- TheStr[ InsertionPoint - 1 ] := CHR( LastKey );
- AtLeadingZero := FALSE;
- END
- ELSE
- IF TheStr[0] = blank THEN
- DumStr[0] := CHR(LastKey);
- IF BeepAtNumbers THEN
- Spkr.TimedNoise( (LastKey * 100) - 4400, 2 );
- END;
- StrEdit.InsertRightJustified( DumStr, TheStr,
- InsertionPoint );
- ELSE
- Spkr.Noise( Spkr.Warble, Spkr.Normal,
- Spkr.Short);
- END;
- END;
- END;
- | Minus: (* '-' *)
- IF AtLeadingZero AND (InsertionPoint > 1) THEN
- IF (TheStr[InsertionPoint - 2] # '-') THEN
- TheStr[ InsertionPoint - 1 ] := CHR( LastKey );
- StrEdit.InsertRightJustified( '0', TheStr,
- InsertionPoint );
- (* Note that we're still AtLeadingZero here. *)
- END;
- END;
- | DecimalKey:
- IF (NOT InDecimals) AND (FloatingPoint OR (DecimalPlaces
- > 0)) THEN
- InDecimals := TRUE;
- INC( InsertionPoint );
- END;
- | Key.BackSpace:
- IF InDecimals THEN
- IF InsertionPoint = (DecimalSpot + 1) THEN
- InDecimals := FALSE;
- DEC( InsertionPoint );
- IF (NOT PosUtils.Present(TheStr[InsertionPoint - 1],
- '0123456789')) THEN
- AtLeadingZero := TRUE;
- StrEdit.InsertRightJustified( '0', TheStr,
- InsertionPoint );
- END;
- ELSE
- IF FloatingPoint THEN
- IF (InsertionPoint = FieldWidth) THEN
- IF (InsertionPoint > (DecimalSpot + 1) ) THEN
- StrEdit.DeleteRightJustified( TheStr,
- InsertionPoint - 1, 1 );
- INC( DecimalSpot );
- ELSE
- InDecimals := FALSE;
- DEC( InsertionPoint );
- END;
- ELSE
- TheStr[ InsertionPoint - 1 ] := '0';
- DEC( InsertionPoint );
- END;
- ELSE
- TheStr[ InsertionPoint - 1 ] := '0';
- DEC( InsertionPoint );
- END;
- END;
- ELSE
- IF NOT AtLeadingZero THEN
- StrEdit.DeleteRightJustified( TheStr,
- InsertionPoint - 1, 1 );
- IF (NOT PosUtils.Present(TheStr[InsertionPoint - 1],
- '0123456789')) THEN
- AtLeadingZero := TRUE;
- IF TheStr[InsertionPoint - 1] = '-' THEN
- (*Get rid of the minus sign, if it's there.*)
- StrEdit.DeleteRightJustified( TheStr,
- InsertionPoint - 1, 1 );
- END;
- StrEdit.InsertRightJustified( '0', TheStr,
- InsertionPoint );
- END;
- END;
- END;
- ELSE
- END;
- UNTIL BigSets.InSet( ExitKeys, LastKey );
- VWindows.SetCursorHeight( WindowHandle, SavedHeight );
- END ReadNumeric;
- BEGIN
- Initialized := FALSE;
- Init();
- END StrInput.
|