home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------*/
- /* filename - tfield.cpp */
- /* */
- /* function(s) */
- /* TField member functions */
- /*------------------------------------------------------------*/
-
- /*------------------------------------------------------------*/
- /* */
- /* Turbo Vision Extensions -- Version 1.1.1 */
- /* */
- /* */
- /* Portions Copyright (c) 1991 by Borland International */
- /* All Rights Reserved. */
- /* */
- /* TV Extensions are Copyright (c) 1992 by Michael Bonner */
- /* These extensions may be freely used by any programmer */
- /* including royalty free inclusion in any commercial */
- /* application, but any commercial rights to the source */
- /* code or object files of the Extensions are reserved. */
- /* */
- /*------------------------------------------------------------*/
-
- #define Uses_ipstream
- #define Uses_MsgBox
- #define Uses_opstream
- #define Uses_TButton
- #define Uses_TDeskTop
- #define Uses_TDialog
- #define Uses_TDrawBuffer
- #define Uses_TEvent
- #define Uses_TField
- #define Uses_TIntField
- #define Uses_TKeys
- #define Uses_TRect
- #define Uses_TStaticText
- #define Uses_TView
-
- #include <tv.h>
- #include "tfield.h"
-
- #if !defined( __CTYPE_H )
- #include <ctype.h>
- #endif // __CTYPE_H
-
- #if !defined( __STRING_H )
- #include <String.h>
- #endif // __STRING_H
-
- #if !defined( __DOS_H )
- #include <Dos.h>
- #endif // __DOS_H
-
- #if !defined( __MEM_H )
- #include <Mem.h>
- #endif // __MEM_H
-
-
- const int CONTROL_Y = 25;
-
- char hotKey( const char *s )
- {
- char *p;
-
- if( (p = strchr( s, '~' )) != 0 )
- return toupper(p[1]);
- else
- return 0;
- }
-
- #define cpField "\x13\x13\x14\x15"
-
-
- const char * const near TField::name = "TField";
- const char near TField::rightArrow = '\x10';
- const char near TField::leftArrow = '\x11';
-
-
- TField::TField( const TRect& bounds, int aMaxLen ) :
- TView(bounds),
- data( new char[aMaxLen] ), // note initialization to [aMaxLen] which is
- maxLen( aMaxLen - 1 ), // maxLen + 1 so later data[maxLen] = EOS
- curPos( 0 ), // is valid!
- firstPos( 0 ),
- selStart( 0 ),
- selEnd( 0 ),
- tfOptions( 0 ),
- hideChar( 0 ),
- securityChar( '*' ),
- fieldSecurity( 0 ),
- currentSecurity( 0 ),
- fieldType( TFieldType )
- {
- state |= sfCursorVis;
- options |= ofSelectable | ofFirstClick | ofPreProcess | ofPostProcess;
- eventMask |= evBroadcast;
-
- fieldName = fieldHint = NULL;
-
- *data = EOS;
- dataChanged = False;
- }
-
- TField::~TField()
- {
- delete data;
-
- if ( fieldName != NULL )
- delete fieldName;
-
- if ( fieldHint != NULL )
- delete fieldHint;
- }
-
- Boolean TField::canScroll( int delta ) //Private
- {
- if( (tfOptions & tfNoScroll) != 0)
- return False;
- else
- {
- if( delta < 0 )
- return Boolean( firstPos > 0 );
- else
- if( delta > 0 )
- return Boolean( strlen(data) - firstPos + 2 > size.x );
- else
- return False;
- };
- }
-
- void TField::convertData( void ) //Virtual
- {
- dataChanged = False;
- }
-
- ushort TField::dataSize() //Virtual
- {
- return maxLen+1;
- }
-
- void TField::deleteSelect() //Private
- {
- if( selStart < selEnd )
- {
- strcpy( data+selStart, data+selEnd );
- curPos = selStart;
- };
- }
-
- void TField::draw() //Virtual
- {
- const int bufferSize = 256;
-
- int selectFirst = 0, // formerly l,
- // used to calc position of the first
- // selected character in the TDrawBuffer
- selectLast = 0, // formerly r,
- // used to calc position of the last
- // selected character in the TDrawBuffer
- dataLen = strlen(data), // holds the length of the data string
- cursorPosition = 0, // holds the new cursor postion
- displaySize = size.x, // holds the # characters of the current
- // TRect which will be used to display data
- dataOffset = firstPos, // holds the offset into the data string
- bufOffset = 0, // holds the offset into the buf buffer
- // used w/ jRight to add leading spaces
- bOffset = 0; // holds the offset into the b buffer
- // used w/ scrollState to leave room for
- // leftArrow
-
- TDrawBuffer b;
-
- uchar color = (state & sfFocused) ? getColor( 2 ) : getColor( 1 );
-
- // clear the display buffer
- b.moveChar( 0, ' ', color, size.x );
-
- char buf[bufferSize]; // create a temporary character buffer
- memset(buf, ' ', (size.x > bufferSize) ? bufferSize : size.x); // clear the buffer
-
- if ( (tfOptions & tfNoScroll) == 0 )
- {
- bOffset = 1; // leave room for the left arrow at the
- // start of the line
- displaySize -= 2; // adjust display size to leave room for
- // two arrows on the line
-
- if ( ((state & sfSelected) != 0 ) &&
- ((state & sfFocused) != 0 ) )
- {
- if( canScroll(1) )
- b.moveChar( size.x-1, rightArrow, getColor(4), 1 );
- if( canScroll(-1) )
- b.moveChar( 0, leftArrow, getColor(4), 1 );
- };
- };
-
- if ( ((tfOptions & tfRight) != 0 ) && (dataLen <= displaySize) )
- {
- bufOffset = displaySize - dataLen;
- if (maxLen < displaySize)
- bufOffset--;
- };
-
- if ( (state & sfSelected) != 0 )
- {
- selectFirst = selStart - firstPos;
- selectLast = selEnd - firstPos;
- selectFirst = max( 0, selectFirst ) + bufOffset;
- selectLast = min( displaySize, selectLast ) + bufOffset;
- cursorPosition = curPos - firstPos + bOffset + bufOffset;
- };
-
-
- if ( hideChar < ' ' )
- // Check for a securityChar situation
- if ( ((tfOptions & tfHideSecure) != 0) &&
- (currentSecurity > fieldSecurity) )
- // We have a security situation so we need to mask the string
- strnset(buf+bufOffset, securityChar , min(displaySize, dataLen-dataOffset) );
- else
- strncpy( buf+bufOffset, data+dataOffset, min(displaySize, dataLen) );
- else
- strnset(buf+bufOffset, hideChar , min(displaySize, dataLen-dataOffset) );
-
- if (bufOffset > 0)
- buf[ displaySize ] = EOS;
- else
- buf[ min(displaySize, dataLen) ] = EOS;
-
- b.moveStr( bOffset, buf, color );
-
- if (selectFirst < selectLast)
- b.moveChar( selectFirst + bOffset, 0, getColor(3),
- min(selectLast - selectFirst, dataLen) );
-
- writeLine( 0, 0, size.x, size.y, b );
-
- setCursor( cursorPosition > size.x ? size.x : cursorPosition, 0);
-
- }
-
- ushort TField::filterCharCode( ushort charCode ) //Virtual
- {
- return charCode;
- // return a 1 to selectAll( true ) the field in the handleEvent routine
- }
-
- void TField::getData( void *rec ) //Virtual
- {
- memcpy( rec, data, dataSize() );
- }
-
- TPalette& TField::getPalette() const //Virtual
- {
- static TPalette palette( cpField, sizeof( cpField )-1 );
- return palette;
- }
-
- void TField::gotFocus( void ) //Virtual
- {
- selectAll( True );
- }
-
- void TField::handleEvent( TEvent& event ) //Virtual
- {
- TView::handleEvent(event);
-
- int delta, anchor, i, selectFlag = 0;
- if( (state & sfSelected) != 0 )
- switch( event.what )
- {
- case evMouseDown:
- if( canScroll(delta = mouseDelta(event)) )
- do
- {
- if( canScroll(delta) )
- {
- firstPos += delta;
- drawView();
- }
- }
- while( mouseEvent( event, evMouseAuto ) );
- else if (event.mouse.doubleClick)
- selectAll(True);
- else
- {
- anchor = mousePos(event);
- do
- {
- if ( event.what == evMouseAuto &&
- canScroll( delta = mouseDelta(event) )
- )
- firstPos += delta;
- curPos = mousePos(event);
- if( curPos < anchor )
- {
- selStart = curPos;
- selEnd = anchor;
- }
- else
- {
- selStart = anchor;
- selEnd = curPos;
- }
- drawView();
- }
- while (mouseEvent(event, evMouseMove | evMouseAuto));
- }
- clearEvent(event);
- break;
-
- case evKeyDown:
- switch( ctrlToArrow(event.keyDown.keyCode) )
- {
- case kbLeft:
- if( curPos > 0 )
- curPos--;
- break;
- case kbRight:
- if( curPos < strlen(data) )
- curPos++;
- break;
- case kbHome:
- curPos = 0;
- break;
- case kbEnd:
- curPos = strlen(data);
- break;
- case kbEnter:
- if ( (tfOptions & tfEnterTabs) != 0 )
- {
- if ( (tfOptions & tfStayError) == 0)
- owner->selectNext( False );
- else
- if( valid(cmLeaving) )
- owner->selectNext( False );
- }
- else
- return;
- break;
- case kbTab:
- if ( (tfOptions & tfStayError) == 0)
- owner->selectNext( False );
- else
- if( valid(cmLeaving) )
- owner->selectNext( False );
- break;
- case kbShiftTab:
- if ( (tfOptions & tfStayError) == 0)
- owner->selectNext( True );
- else
- if( valid(cmLeaving) )
- owner->selectNext( True );
- break;
- case kbBack:
- if( curPos > 0 )
- {
- dataChanged = True;
- strcpy( data+curPos-1, data+curPos );
- curPos--;
- if( firstPos > 0 )
- firstPos--;
- }
- break;
- case kbCtrlBack:
- dataChanged = True;
- *data = EOS;
- curPos = 0;
- break;
- case kbDel:
- dataChanged = True;
- if( selStart == selEnd )
- if( curPos < strlen(data) )
- {
- selStart = curPos;
- selEnd = curPos + 1;
- }
- deleteSelect();
- break;
- case kbIns:
- setState(sfCursorIns, Boolean(!(state & sfCursorIns)));
- break;
- default:
- if ( processKeyCode(event.keyDown.keyCode) == 1 )
- selectFlag = 1;
-
- ushort holdCharCode =
- filterCharCode(event.keyDown.charScan.charCode);
-
- if( holdCharCode >= ' ' )
- {
- dataChanged = True;
- // Added fix for overlay mode suggested by
- // Martin Keye (CIS 100033,3020)
- // Line read:
- // if ( (state & sfCursorIns ) != 0 )
- if ( ((state & sfCursorIns ) != 0) &&
- (curPos < strlen(data)) )
- strcpy( data + curPos, data + curPos + 1 );
- else
- deleteSelect();
-
- if( strlen(data) < maxLen )
- {
- if( firstPos > curPos )
- firstPos = curPos;
- memmove( data + curPos + 1, data + curPos,
- strlen(data+curPos)+1 );
- data[curPos++] = holdCharCode;
- }
- else
- {
- dataChanged = False;
- if ( (tfOptions & tfBeepError) != 0)
- beep();
- };
- }
- else
- {
- if( holdCharCode == CONTROL_Y)
- {
- dataChanged = True;
- *data = EOS;
- curPos = 0;
- }; // if control_y
- if ( holdCharCode == 1 )
- selectFlag = 1;
- };
- }; // switch
- if (selectFlag == 1)
- curPos = selEnd = strlen( data );
- else
- selStart = selEnd = 0;
- if( (maxLen == 1) && (size.x == 1) )
- firstPos = curPos = 0;
- else
- {
- if( firstPos > curPos )
- firstPos = curPos;
- i = curPos - size.x + 1;
- if ((tfOptions & tfNoScroll) == 0)
- i += 2;
- if( firstPos < i )
- firstPos = i;
- };
- drawView();
- clearEvent( event );
- break;
-
- case evBroadcast:
-
- if (event.message.command == cmUpdateSecurity)
- setCurrentSecurity( event.message.infoWord );
-
- if ( (event.message.infoPtr == this) &&
- ((state & sfExposed) != 0) )
- {
- ushort saveEvents;
- switch (event.message.command)
- {
- case cmReceivedFocus:
- saveEvents = eventMask;
- eventMask &= ~evBroadcast;
- gotFocus();
- clearEvent(event);
- eventMask = saveEvents;
- break;
-
- case cmReleasedFocus:
- saveEvents = eventMask;
- eventMask &= ~evBroadcast;
- lostFocus();
- clearEvent(event);
- eventMask = saveEvents;
- break;
- };
- };
- };
- }
-
- #pragma argsused
- Boolean TField::isValid( ushort command ) //Virtual
- {
- Boolean status = True;
-
- // skeleton for overriding
- /* switch (command)
- {
- case cmArriving:
- // handle dependence based on other field's values, etc.
- status = True;
- break;
-
- case cmLeaving:
- // perform custom validations
- status = True;
- break;
-
- }; */
-
- return status;
- }
-
- void TField::lostFocus( void ) //Virtual
- {
- selectAll( False );
- }
-
- int TField::mouseDelta( TEvent& event ) //Private
- {
- TPoint mouse = makeLocal( event.mouse.where );
-
- if( mouse.x <= 0 )
- return -1;
- else
- if( mouse.x >= size.x - 1 )
- return 1;
- else
- return 0;
- }
-
- int TField::mousePos( TEvent& event ) //Private
- {
-
- TPoint mouse = makeLocal( event.mouse.where );
- int pos;
-
- int leadArrow = (((tfOptions & tfNoScroll) != 0) ? 0 : 1),
- // offset for the beginning arrow
- displaySize = (((tfOptions & tfNoScroll) != 0) ? size.x : size.x - 2),
- // x size used for display
- dataLen = strlen(data), // length of the data item
- jOffset = 0; // justification offset
-
- if ( ((tfOptions & tfRight) != 0) && (dataLen <= displaySize) )
- {
- jOffset = displaySize - dataLen;
- if (maxLen < displaySize)
- jOffset--;
- };
-
- mouse.x = max( mouse.x, leadArrow );
- pos = mouse.x + firstPos - jOffset - leadArrow;
-
- pos = max( pos, 0 );
- pos = min( pos, strlen(data) + jOffset );
- return pos;
- }
-
- ushort TField::processKeyCode( ushort keyCode ) //Virtual
- {
- return keyCode;
- // return a 1 to selectAll( true ) the field in the handleEvent routine
- }
-
-
- void TField::selectAll( Boolean enable )
- {
- selStart = 0;
- if( enable )
- curPos = selEnd = strlen(data);
- else
- curPos = selEnd = 0;
-
- if ((tfOptions & tfNoScroll) != 0)
- if ( (maxLen == 1) && (size.x == 1) )
- firstPos = 0;
- else
- firstPos = max( 0, curPos-size.x+1 );
- else
- firstPos = max( 0, curPos-size.x+3 );
- drawView();
- }
-
- void TField::setCurrentSecurity( ushort newSecurityLevel ) //Virtual
- {
- currentSecurity = newSecurityLevel;
-
- if ( (tfOptions & tfHideSecure) != 0 )
- if (currentSecurity > fieldSecurity)
- drawView();
-
- }
-
- void TField::setData( void *rec ) //Virtual
- {
- memcpy( data, rec, dataSize()-1 );
- data[dataSize()-1] = EOS;
- selectAll( True );
- }
-
- void TField::setFieldHint( char *aString ) //Virtual
- {
- if (fieldHint != NULL)
- delete fieldHint; // free old storage
-
- fieldHint = newStr( aString );
- }
-
- void TField::setFieldName( char *aString) //Virtual
- {
- if (fieldName != NULL)
- delete fieldName; // free old storage
-
- fieldName = newStr( aString );
- }
-
- void TField::setHideChar( char newHideChar ) //Virtual
- {
- hideChar = newHideChar;
- drawView();
- }
-
- void TField::setTFOptions( ushort anOption, Boolean enable ) //Virtual
- {
- if( enable == True )
- tfOptions |= anOption;
- else
- tfOptions &= ~anOption;
-
- if( (anOption & tfNoScroll) && enable )
- firstPos = 0;
-
- drawView();
-
- }
-
- Boolean TField::valid( ushort command ) //Virtual
- {
- Boolean status = True;
-
- if (dataChanged)
- convertData(); // for later implementation, handle customized data types
-
- switch (command)
- {
-
- case cmValid:
- status = True;
- break;
-
- case cmLeaving:
- if ( (tfOptions & tfPreValidate) != 0)
- status = isValid(command);
-
- if (status)
- {
- if ( ((tfOptions & tfMustFill) != 0) &&
- ( strlen(data) < maxLen ) )
- {
- status = False;
- if ((tfOptions & tfBeepError) != 0)
- beep();
- messageBox("This field must be completely filled!",
- mfWarning | mfOKButton );
- }
- else
- if ( ((tfOptions & tfNotEmpty) != 0) &&
- ( strlen(data) == 0 ) )
- {
- status = False;
- if ((tfOptions & tfBeepError) != 0)
- beep();
- messageBox("This field must contain at least 1 character!",
- mfWarning | mfOKButton );
- };
- };
-
- if (status)
- if ( (tfOptions & tfPreValidate) == 0)
- status = isValid(command);
-
- break;
-
- case cmArriving:
- if ( (tfOptions & tfPreValidate) != 0)
- status = isValid(command);
-
- if (status)
- status = True;
-
- if (status)
- if ( (tfOptions & tfPreValidate) != 0)
- status = isValid(command);
-
- break;
-
- };
-
- return status;
- }
-
- void TField::write( opstream& os ) //Protected
- {
- TView::write( os );
- os << maxLen << curPos << firstPos
- << selStart << selEnd << tfOptions << hideChar
- << securityChar << fieldSecurity << currentSecurity;
- os.writeString( data);
- os.writeString(fieldHint);
- os.writeString(fieldName);
- os << fieldType;
- }
-
- void *TField::read( ipstream& is ) //Protected
- {
- TView::read( is );
- is >> maxLen >> curPos >> firstPos
- >> selStart >> selEnd >> tfOptions >> hideChar
- >> securityChar >> fieldSecurity >> currentSecurity;
-
- if ((data = new char[maxLen + 1]) != NULL)
- is.readString(data, maxLen);
-
- char *buffer;
- if ((buffer = new char[256]) != NULL)
- {
- is.readString(buffer, 255);
- fieldHint = newStr(buffer);
- is.readString(buffer, 255);
- fieldName = newStr(buffer);
- delete buffer;
- };
-
- is >> fieldType;
-
- state |= sfCursorVis;
-
- options |= ofSelectable | ofFirstClick | ofPreProcess | ofPostProcess;
- eventMask |= evBroadcast;
- return this;
- }
-
- TStreamable *TField::build()
- {
- return new TField( streamableInit );
- }
-
- TField::TField( StreamableInit ) : TView( streamableInit ) //Protected
- {
- }
-