home *** CD-ROM | disk | FTP | other *** search
- // Zinc Interface Library - STRING.CPP
- // COPYRIGHT (C) 1990, 1991. All Rights Reserved.
- // Zinc Software Incorporated. Pleasant Grove, Utah USA
-
- #include "ui_win.hpp"
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
-
- UIW_STRING::UIW_STRING(int left, int top, int width, char *a_text,
- short maxLength, USHORT a_stFlags, USHORT woFlags,
- int (*a_Validate)(void *object, int ccode)) :
- UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
- {
- windowID[0] = ID_STRING;
- search.type = ID_STRING;
- stFlags = a_stFlags;
-
- Validate = a_Validate;
- originalWidth = fieldWidth = width;
- // NOTE: in-field scrolling is not currently supported for right-justified
- // and center-justified strings. The following line enforces that by
- // disallowing the "maxLength" from being larger than the field width in
- // those cases.
- if (FlagSet(woFlags, WOF_JUSTIFY_RIGHT | WOF_JUSTIFY_CENTER))
- maxLength = Min(maxLength, width);
- if (FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
- text = a_text;
- else
- {
- text = new char[maxLength];
- if (a_text)
- {
- int srcLen = strlen(a_text) + 1;
- memcpy(text, a_text, Min(srcLen, maxLength));
- }
- else
- text[0] = '\0';
- }
- insertMode = (width <= 2) ? FALSE : TRUE;
- textTail = text + maxLength - 1;
- *textTail = '\0'; // Insure trailing null.
- screen = 0;
- screenSize = 0;
- screenMarkStart = 0;
- screenMarkTail = 0;
- }
-
- UIW_STRING::~UIW_STRING()
- {
- if (!FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
- delete text;
- if (screen)
- delete screen;
- }
-
- int UIW_STRING::Event(const UI_EVENT &event)
- {
- int viewOnly = FlagSet(woFlags, WOF_VIEW_ONLY) ||
- FlagSet(woAdvancedStatus, WOAS_TOO_SMALL) ? TRUE : FALSE;
- int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_STRING);
- UI_REGION region;
- UI_WINDOW_OBJECT::Border(0, region, 0);
- USHORT key;
- short cellWidth = display->TextWidth("W");
- short width = (region.right + 1 - region.left) / cellWidth;
- UCHAR reDisplay = TRUE;
- UCHAR displayCheckRegion = FALSE;
- int needValidate = NeedsValidation();
-
- if (ccode == S_SIZE)
- {
- int width = (relative.right - relative.left + 1) / display->cellWidth;
- if (width != originalWidth)
- {
- originalWidth = width;
- ccode = S_CREATE;
- }
- }
- if (ccode == S_CREATE)
- {
- markedBlock = 0;
- screenTop = text;
- cursor = text;
- if (FlagSet(woFlags, WOF_BORDER))
- fieldWidth = display->isText ? originalWidth - 2 : originalWidth - 1;
- else
- fieldWidth = originalWidth;
- // NOTE: Prevent in-field scrolling in right-justified and center-
- // justified fields by limiting maximum size of string to fit in
- // the field width in those cases.
- if (FlagSet(woFlags, WOF_JUSTIFY_RIGHT | WOF_JUSTIFY_CENTER) &&
- textTail + 1 - text > fieldWidth)
- textTail = text + fieldWidth - 1;
- }
- textNull = strchr(text, '\0');
- if (textNull < cursor)
- cursor = textNull;
-
- /* Switch on the event type */
- switch (ccode)
- {
- case E_KEY:
- key = event.rawCode & 0xFF;
- if (!viewOnly)
- {
- if (key == '\b')
- BackspaceKey();
- else if (FlagSet(stFlags, STF_VARIABLE_NAME))
- RegularKey((key == ' ') ? '_' : toupper(key));
- else
- RegularKey(key);
- }
- else
- {
- reDisplay = FALSE;
- ccode = S_UNKNOWN;
- }
- break;
-
- case L_LEFT:
- if (cursor == text)
- {
- ccode = S_UNKNOWN;
- reDisplay = FALSE;
- }
- else
- {
- MoveOperation();
- LeftArrow();
- CheckLeftScroll();
- }
- break;
-
- case L_RIGHT:
- if (*cursor)
- {
- MoveOperation();
- cursor++;
- CheckRightScroll();
- }
- else
- {
- ccode = S_UNKNOWN;
- reDisplay = FALSE;
- }
- break;
-
- case L_BOL:
- MoveOperation();
- screenTop = text;
- cursor = text;
- break;
-
- case L_EOL:
- if (*cursor)
- {
- MoveOperation();
- cursor = textNull;
- if (textNull < text + fieldWidth)
- screenTop = text;
- else
- screenTop = textNull - fieldWidth + 1;
- }
- break;
-
- case L_WORD_LEFT:
- MoveOperation();
- WordTabLeft();
- CheckLeftScroll();
- break;
-
- case L_WORD_RIGHT:
- if (*cursor)
- {
- MoveOperation();
- while ( NonWhiteSpace(*cursor) )
- cursor++;
- while (*cursor && WhiteSpace(*cursor) )
- cursor++;
- CheckRightScroll();
- }
- break;
-
- case L_INSERT_TOGGLE:
- MoveOperation();
- insertMode = !insertMode;
- break;
-
- case L_DELETE:
- if (!viewOnly)
- {
- SetMark();
- if (markStart)
- {
- pasteLength = (USHORT) (markTail - markStart);
- DeleteBlock(markStart, pasteLength);
- }
- else if (*cursor)
- DeleteBlock(cursor, 1);
- }
- break;
-
- case L_DELETE_EOL:
- if (!viewOnly)
- DeleteEol();
- break;
-
- case L_DELETE_WORD:
- if (!viewOnly)
- DeleteWord();
- break;
-
- case L_MARK:
- if (markedBlock)
- markedBlock = 0; // Toggle mark off if its on.
- else
- markedBlock = cursor; // Or turn it on if its off.
- break;
-
- case L_VIEW:
- eventManager->DeviceState(event.type, DM_EDIT);
- reDisplay = FALSE;
- break;
-
- case L_CUT:
- if (!viewOnly)
- {
- SetMark();
- if (markStart)
- {
- pasteLength = (USHORT) (markTail - markStart);
- DeleteBlock(markStart, pasteLength);
- }
- else
- reDisplay = FALSE;
- break;
- }
- // If view only, treat a CUT as a copy.
-
- case L_COPY_MARK:
- SetMark();
- if (markStart)
- CopyBlock();
- else
- reDisplay = FALSE;
- break;
-
- case L_CUT_PASTE:
- SetMark();
- if (markStart)
- {
- if (viewOnly)
- CopyBlock();
- else
- {
- pasteLength = (USHORT) (markTail - markStart);
- DeleteBlock(markStart, pasteLength);
- }
- break;
- }
- /*** else fall through to paste code. ***/
- case L_PASTE:
- if (!viewOnly)
- {
- if (event.type != E_KEY)
- {
- MoveOperation();
- int leading = CalcLeading(width);
- int fieldColumn = (event.position.column - region.left) / cellWidth;
- cursor = screenTop + fieldColumn - leading;
- if (cursor > textNull)
- cursor = textNull;
- else if (cursor < text)
- cursor = text;
- UpdateCursor(region, width);
- }
- PasteBlock();
- }
- break;
-
- case L_END_MARK:
- if (cursor == markedBlock)
- markedBlock = 0; // Eliminate zero-length mark.
- reDisplay = FALSE;
- break;
-
- case L_CONTINUE_MARK:
- if (markedBlock)
- {
- MoveOperation();
- int leading = CalcLeading(width);
- if (event.position.column > region.left)
- cursor = screenTop + (event.position.column - region.left) / cellWidth - leading;
- else
- cursor = screenTop;
- if (cursor > textNull)
- cursor = textNull;
- else if (cursor < text)
- cursor = text;
- UpdateCursor(region, width);
- break;
- }
- /*** Else fall through to code that begins the mark. */
- case L_BEGIN_MARK:
- {
- int leading = CalcLeading(width);
- int fieldColumn = (event.position.column - region.left) / cellWidth;
- cursor = screenTop + fieldColumn - leading;
- if (cursor > textNull)
- cursor = textNull;
- else if (cursor < text)
- cursor = text;
- if (fieldColumn == 0)
- CheckLeftScroll();
- else if (fieldColumn >= fieldWidth - 1 && cursor < textNull)
- {
- cursor++;
- CheckRightScroll();
- }
- UpdateCursor(region, width);
- markedBlock = cursor; // Throw away possible old mark.
- }
- break;
-
- case S_ERROR_RESPONSE:
- woStatus |= event.rawCode;
- break;
-
- case S_CURRENT:
- if (needValidate)
- (*Validate)(this, ccode);
- // Clear the WOS_UNANSWERED and WOS_NO_AUTO_CLEAR bits
- woStatus &= ~(WOS_UNANSWERED | WOS_NO_AUTO_CLEAR);
- // Fall through.
-
- case S_DISPLAY_ACTIVE:
- displayCheckRegion = TRUE;
- break;
-
- case S_NON_CURRENT:
- if (needValidate && (*Validate)(this, ccode) != 0 )
- {
- ccode = S_ERROR;
- woStatus |= WOS_INVALID;
- break;
- }
- woStatus &= ~WOS_INVALID; // Clear invalid status bit.
- // else fall through.
- case S_DISPLAY_INACTIVE:
- markedBlock = 0; // Throw away marked block.
- displayCheckRegion = TRUE;
- break;
-
- default:
- ccode = UI_WINDOW_OBJECT::Event(event);
- reDisplay = FALSE;
- break;
- }
- if (displayCheckRegion)
- {
- if ( !UI_WINDOW_OBJECT::NeedsUpdate(event, ccode) )
- {
- reDisplay = FALSE;
- if (ccode == S_CURRENT)
- UpdateCursor(region, width);
- }
- else
- {
- screenInvalid = TRUE;
- UI_WINDOW_OBJECT::Border(ccode, region, lastPalette);
- }
- }
- if (reDisplay)
- {
- SetMark();
- if (cursor - screenTop >= fieldWidth)
- screenTop = cursor - fieldWidth + 1;
- else if (cursor < screenTop)
- screenTop = cursor;
- Redisplay(ccode);
- }
- return (ccode);
- }
-
- #ifdef ZIL_LOAD
- UIW_STRING::UIW_STRING(const char *name, UI_STORAGE *file, USHORT loadFlags) :
- UI_WINDOW_OBJECT(name, file, loadFlags | L_SUB_LEVEL)
- {
- windowID[0] = ID_STRING;
-
- if (!file)
- file = _storage;
- originalWidth = fieldWidth = relative.right - relative.left + 1;
- file->Load(&stFlags);
- short maxLength;
- file->Load(&maxLength);
- text = new char[maxLength];
- short size;
- file->Load(&size);
- if (size)
- file->Load(text, size);
- text[size] = '\0';
- textTail = text + maxLength - 1;
- insertMode = TRUE;
- *textTail = '\0';
- screen = 0;
- screenSize = 0;
- screenMarkStart = 0;
- screenMarkTail = 0;
- if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
- delete file;
- }
- #endif
-
- #ifdef ZIL_STORE
- void UIW_STRING::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
- {
- UI_WINDOW_OBJECT::Store(name, file, storeFlags | S_SUB_LEVEL);
- file->Store(stFlags);
- short maxLength = (short)(textTail - text + 1);
- file->Store(maxLength);
- file->Store(text);
- if (!FlagSet(storeFlags, S_SUB_LEVEL))
- file->ObjectSize(name, search);
- }
- #endif
-