D:\Atwin32.dev\Samples\UIEX\UIEX3
D:\Atwin32.dev\Samples\UIEX\UIEX4
  1|*
  2|**************************************************************************
  3|* Copyright (c) 2004 Schellenbach & Associates, Inc. dba AccuSoft        *
  4|* Enterprises as an unpublished work. Permission is hereby granted, free *
  5|* of charge, to any person obtaining a copy of this software, to use the *
  6|* software without restriction, including without limitation the rights  *
  7|* to use, copy, modify, merge, publish or distribute the software, and   *
  8|* to permit persons to whom the software is furnished to do so, subject  *
  9|* to the following conditions: This copyright notice and permission      *
 10|* notice shall be included in all copies or substantial portions of the  *
 11|* software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY    *
 12|* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES  *
 13|* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND               *
 14|* NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR *
 15|* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF         *
 16|* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION     *
 17|* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.        *
 18|**************************************************************************
 19|**************************************************************************
 20|*
 21|* USER INTERFACE EXAMPLE PROGRAM 3
 22|*
 23|**************************************************************************
 24|**************************************************************************
 25|*
 26|* This example illustrates a character-based interface which uses AccuTerm
 27|Visual Styles to display screen elements using a Windows-like look (if
 28|available). In this exampleVisual Styles (border effects and colors)
 29|are associated with certain display attributes. The program will run
 30|without Visual Styles if used with dumb terminalsolder versions of
 31|* AccuTerm or other terminal emulators. This example incorporates AccuTerm
 32|Imaging to display a picture associated with each customer record (if
 33|available).
   
   
   
   
   
   
   
   
 34|*
 35|**************************************************************************
 36|*
 37|* The CUST.REC INCLUDE item declares the CUST.REC array, which is used to
 38|* store a working copy of the current data record. It also defines the
 39|* record layout by equating field names to array positions in the CUST.REC
 40|* array.
 41|*
 42|$INCLUDE UIEX.CUST.REC
 43|*
 44|**************************************************************************
 45|*
 46|* EQUates for control characters and delimiters and other constants
 47|*
 48|EQU VM TO CHAR(253)
 49|EQU BEL TO CHAR(7)
 50|EQU ESC TO CHAR(27)
 51|EQU STX TO CHAR(2)
 52|EQU CR TO CHAR(13)
 53|EQU FALSE TO 0
 54|EQU TRUE TO 1
 55|*
 56|**************************************************************************
 57|*
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
 58|* This program uses AccuTerm Imaging to display pictures associated with
 59|* records in the customer file. This EQUate defines the path where the
 60|* image files are located.
 61|*
 62|EQU PIX.PATH TO 'http://www.asent.com/demo/PIX/'
 63|*
 64|* Check for image support (no images for dumb terminal or AccuTerm Lite)
 65|*
 66|CALL FTVSINF('','','',CAPABILITIES,'','','','')
 67|IF INDEX(CAPABILITIES,'I',1) THEN IMGFLG = TRUE ELSE IMGFLG = FALSE
 68|*
 69|**************************************************************************
 70|*
 71|* Open our files...
 72|*
 73|OPEN 'CUST.SAMPLE' TO FN.CUST ELSE PRINT 'NO CUST.SAMPLE FILE';STOP
 74|OPEN 'DICT CUST.SAMPLE' TO FN.DICT.CUST ELSE PRINT 'NO DICT CUST.SAMPLE FILE';STOP
 75|OPEN 'CUST.SAMPLE.XREF' TO FN.CUST.XREF ELSE PRINT 'NO CUST.SAMPLE.XREF';STOP
 76|*
 77|**************************************************************************
 78|*
 79|* Define the data field control structures. NUMFLDS is the number of
 80|* fields. The CONTROL array defines the field control elements such as
 81|* field label, label position, field position and size, and field prompt.
 82|* The IDATA array stores the current field values, and is initialized from
 83|* the CUST.REC array when a data record is read from the file. When the
 84|* record is updated, values are copied from the IDATA array to the
 85|* CUST.REC array and the CUST.REC array is passed to the CUST.UPDATE
 86|* subroutine to update the data and index files (a separate subroutine is
 87|* used to update the file since the update process may handle other
 88|* functions like updating indexes).
 89|*
 90|NUMFLDS = 12
 91|DIM CONTROL(12)
 92|DIM IDATA(12)
 93|*
 94|* Define field control elements
 95|*  value 1: field label text
 96|*  value 2: field label column
 97|*  value 3: field label row
 98|*  value 4: field label width (0 for actual width, no padding)
 99|*  value 5: field data column
100|*  value 6: field data row
101|*  value 7: field data width
102|*  value 8: field data height
103|*  value 9: field prompt message
104|CONTROL(1) = 'Customer IDý7ý2ý20ý28ý2ý30ý1ýEnter the ID, or name to search for, or N for next number'
105|CONTROL(2) = 'Contactý7ý4ý20ý28ý4ý30ý1ýEnter the contact name'
106|CONTROL(3) = 'Company nameý7ý5ý20ý28ý5ý30ý1ýEnter the company name'
107|CONTROL(4) = 'Address line 1ý7ý6ý20ý28ý6ý30ý1ýEnter address line 1'
108|CONTROL(5) = 'Address line 2ý7ý7ý20ý28ý7ý30ý1ýEnter address line 2'
109|CONTROL(6) = 'Cityý7ý8ý20ý28ý8ý25ý1ýEnter the city'
110|CONTROL(7) = 'State or provinceý7ý9ý20ý28ý9ý15ý1ýEnter the state or province abbreviation'
111|CONTROL(8) = 'Zip/postal codeý7ý10ý20ý28ý10ý10ý1ýEnter the zip or postal code'
112|CONTROL(9) = 'Countryý7ý11ý20ý28ý11ý18ý1ýEnter the country'
113|CONTROL(10) = 'Phoneý7ý12ý20ý28ý12ý15ý1ýEnter the phone number'
114|CONTROL(11) = 'Faxý7ý13ý20ý28ý13ý15ý1ýEnter the fax number'
115|CONTROL(12) = 'Notesý7ý14ý20ý28ý14ý30ý1ýEnter any notes about this customer'
116|*
117|**************************************************************************
118|*
119|* Define some screen control strings for prompts & errors
120|*
121|PROMPT ''
122|CLR = @(-1)        ;* Clear entire screen
123|CEOL = @(-4)       ;* Clear to end of line
124|PL = @(5,22):CEOL  ;* Prompt line
125|EL = @(5,23):CEOL  ;* Error line
126|*
127|* Wyse 60 attributes for NORMAL, REVERSE, DIM REVERSE and UNDERLINE
128|* REVERSE (we like Wyse 60 because the attributes dont take any space on
129|* the screen, and more than one attribute can be displayed at one time).
130|* If running AccuTerm in Viewpoint A2 Enhanced emulation, you can use the
131|* ADDS 4000 attributes instead. Just change the upper-case "G" below to
132|* lower-case "g".
133|*
134|NORMAL = ESC:'G0'  ;* Normal - display headings & field labels
135|REVERSE = ESC:'G4' ;* Reverse - display active field data
136|DIMREV = ESC:'Gt'  ;* Dim Reverse - display inactive field data
137|UNDREV = ESC:'G<'  ;* Underline Reverse - display warnings
138|*
139|**************************************************************************
140|*
141|* This program processes one customer record at a time, and is organized
142|* using three nested loops. The outermost loop (the RECORD loop) is
143|* executed once for each record accessed. The loop repeats until the EXIT
144|* control variable is set to TRUE.
145|*
146|EXIT = FALSE
147|LOOP UNTIL EXIT DO
148| *
149| *************************************************************************
150| *
151| * Before prompting for the customer ID, reset the internal data array
152| * (IDATA) and CUST.ID variables, then clear the screen and display the
153| * heading and field labels.
154| * 
155| GOSUB RESTART
156| GOSUB DSPSCRN
157| *
158| *************************************************************************
159| *
160| * The middle loop is the ACTION loop. It is executed for the current
161| * record until the user performs an action that terminates processing of
162| * that record, such as exiting, cancelling, saving or deleting the
163| * record. The field number to begin prompting (NXTFLD) is initialized to
164| * 1, causing the ID field to be prompted first. The loop immediately
165| * enters the PROMPT loop, followed by the field modification prompt. The
166| * loop repeats until the DONE control variable is set to TRUE.
167| *
168| NXTFLD = 1
169| DONE = FALSE
170| LOOP
171|  *
172|  ************************************************************************
173|  *
174|  * The inner loop is the PROMPT loop. It is executed for each prompt
175|  * field as specified by the NXTFLD variable. The prompt loop simply
176|  * calls the local INPUT.FIELD subroutine which performs field input,
177|  * data validation and keyboard command decoding. The FIELD loop repeats
178|  * until the field number is greater than the number of fields, or until
179|  * the DONE control variable is set to TRUE. The DONE control variable
180|  * may be set to TRUE in the INPUT.FIELD subroutine, if the user enters a
181|  * NULL to for the item-ID.
182|  *
183|  LOOP
184|   CURFLD = NXTFLD
185|  UNTIL DONE OR CURFLD > NUMFLDS DO
186|   *
187|   ***********************************************************************
188|   *
189|   * Prompt for the next field. Update the NXTFLD variable with the field
190|   * number to prompt next.
   
191|   *
192|   GOSUB INPUT.FIELD
193|  REPEAT ;* end of PROMPT loop
194|  *
195|  ************************************************************************
196|  *
197|  * If the FIELD loop exited with the DONE control variable set to TRUE,
198|  * bypass the modification prompt because no action is required.
199|  * Otherwise, prompt for which field to modify, or other actions such as
200|  * save or delete.
201|  *
202|  IF NOT(DONE) THEN
203|   *
204|   NXTFLD = NUMFLDS + 1 ;* assume we need to reprompt for action
205|   *
206|   PRINT PL:'Enter field number to modify or FI to save, DE to delete, EX to exit: ':
207|   INPUT ANS:
208|   PRINT EL:
209|   *
210|   ***********************************************************************
211|   *
212|   * Decode the response
213|   *
214|   ANS = OCONV(ANS, 'MCU')
215|   BEGIN CASE
216|    CASE NUM(ANS) AND ANS >= 1 AND ANS <= NUMFLDS; NXTFLD = ANS
217|    CASE ANS EQ 'FI'; GOSUB SAVE.RECORD
218|    CASE ANS EQ 'DE'; GOSUB DELETE.RECORD
219|    CASE ANS EQ 'EX' OR ANS EQ ''; GOSUB CHECK.EXIT
220|   END CASE 
221|   *  
222|  END
223|  *
224| UNTIL DONE DO REPEAT ;* end of ACTION loop
225| *
226|REPEAT ;* end of RECORD loop
227|*
228|**************************************************************************
229|*
230|* All done - clear the screen and exit!
231|PRINT CLR:
232|STOP
233|*
234|*
235|**************************************************************************
236|**************************************************************************
237|* LOCAL SUBROUTINES
238|**************************************************************************
239|**************************************************************************
240|*
241|*
242|**************************************************************************
243|*
244|* The INPUT.FIELD subroutine is the main prompting routine. This routine
245|* displays the prompt string (from the CONTROL array), and enters a loop,
246|* prompting for a specified field (CURFLD) and setting the next field
247|* variable (NXTFLD) appropriately. The loop repeats until the NXTFLD
248|* (initially set to CURFLD) changes. This causes the field prompt to be
249|* repeated in case invalid data is entered (illegal customer IDetc.) If
250|a NULL is entered for the ID fieldand there is no current record, the
251|ACTION loop control variable, DONE, and the RECORD loop control
252|* variable, EXIT, are set to TRUE, and this routine exits.
   
   
253|*
254|INPUT.FIELD: 
255|*
256|**************************************************************************
257|*
258|* Display the prompt message
259|*
260|PRINT PL:CONTROL(CURFLD)<1,9>:
261|*
262|**************************************************************************
263|*
264|* Initialize current value, next field
265|*
266|PREVAL = IDATA(CURFLD) ;* Save previous field value to detect change in value
   
   
   
267|*
268|**************************************************************************
269|*
270|* Prompt for this field until NXTFLD variable is updated
271|*
272|LOOP
273| *
274| *************************************************************************
275| *
276| * Assume next field number is next sequential field
277| *
278| NXTFLD = CURFLD + 1
279| *
280| * Highlight current field data
281| *
282| XLINE = CURFLD  ;* Set the field number to display
283| ACTIVE = CURFLD ;* Set the active field number to highlight field
284| GOSUB DSPLINE
285| *
286| * Prompt for input
287| *
288| PRINT @(CONTROL(CURFLD)<1,5>,CONTROL(CURFLD)<1,6>):REVERSE:
289| INPUT IDATA(CURFLD):
290| *
291| * Check for NULL
292| *
293| K = LEN(IDATA(CURFLD))
294| IF K = 0 THEN
295|  *
296|  * No change if NULL entered
297|  *
298|  IDATA(CURFLD) = PREVAL
299| END ELSE
300|  *
301|  * Erase old data
302|  *
303|  IF K < CONTROL(CURFLD)<1,7> THEN
304|   PRINT @(K+CONTROL(CURFLD)<1,5>,CONTROL(CURFLD)<1,6>):SPACE(CONTROL(CURFLD)<1,7> - K):
305|  END
   
   
   
   
   
306| END
307| *
308| * Reset display attribute
309| *
310| PRINT NORMAL:
311| *
312| * Clear the error line
313| *
314| PRINT EL:
315| *
316| *************************************************************************
317| *
318| * Check for any special values (like 'END' or 'EXIT')
319| *
320| IF OCONV(IDATA(CURFLD),'MCU') EQ 'END' THEN
321|  IDATA(CURFLD) = PREVAL ;* Restore previous value
322|  GOSUB CHECK.ABANDON ;* Ensure OK to loose changes
323|  IF OK THEN
324|   *
325|   ***********************************************************************
326|   *
327|   * No changes, or user OKs abandoning them, so we are outa here!
328|   *
329|   DONE = TRUE
330|   EXIT = TRUE
331|   RETURN
332|   *
333|  END ELSE
334|   *
335|   ***********************************************************************
336|   *
337|   * User does not want to abandon changes, so reprompt
   
338|   *
   
   
339|   NXTFLD = CURFLD ;* Reprompt
340|   *
341|  END
342| END
343| IF IDATA(CURFLD) EQ SPACE(LEN(IDATA(CURFLD))) THEN IDATA(CURFLD) = ''
344| *
345| *************************************************************************
346| *
347| * Peform field data validation if next field number changed
348| *
349| IF NXTFLD NE CURFLD THEN
350|  BEGIN CASE
351|   *
352|   CASE CURFLD EQ 1
353|    *
354|    **********************************************************************
355|    *
356|    * Validate the ID field. If NULL, quit. If changed, read new record.
357|    *
358|    IF CUST.ID EQ '' AND IDATA(CURFLD) EQ '' THEN
359|     DONE = TRUE
360|     EXIT = TRUE
361|     RETURN
362|    END
363|    *
364|    IF IDATA(CURFLD) NE PREVAL THEN
365|     ID = IDATA(CURFLD)
366|     GOSUB CHECK.ID ;* Check the newly entered ID handling index lookups
367|     IF OK THEN
368|      *
369|      ********************************************************************
370|      *
371|      * New ID (or result of index lookup) is good!
372|      *
373|      IDATA(CURFLD) = ID ;* Update the current field value in case of index lookup
374|      *
375|     END ELSE
376|      *
377|      ********************************************************************
378|      *
379|      * New ID is invalid
380|      *
381|      IDATA(CURFLD) = PREVAL ;* Restore previous value
   
   
382|      NXTFLD = CURFLD ;* Reprompt
383|      *
384|     END
385|    END
386|    *
387|  END CASE
388| END
389| *
390|WHILE CURFLD EQ NXTFLD DO REPEAT
391|*
392|* Redisplay the field data using the inactive highlighting
393|*
394|XLINE = CURFLD
395|ACTIVE = 0
396|GOSUB DSPLINE
397|*
398|RETURN
399|*
400|*
401|**************************************************************************
402|*
403|* The CHECK.EXIT subroutine checks if any field data has changed, and
404|* prompts if the user wants to abandon changes. If no changes, or the user
405|* decides to abandon the changes, the DONE and EXIT loop control variables
406|* are set to TRUE, causing all three loops to terminate, and the program
407|* itself to exit.
408|*
409|CHECK.EXIT: *
410|*
411|GOSUB CHECK.ABANDON
412|IF OK THEN
413| DONE = TRUE
414| EXIT = TRUE
415| GOSUB HIDEPIX
416|END
417|RETURN
418|*
419|*
420|**************************************************************************
421|*
422|* The CHECK.ID subroutine validates a newly entered item-ID. If the
423|* current record has unsaved changes, the user is prompted to abandon the
424|* changes. If no changes, or the user abandons the changes, and the new ID
425|* is not NULL, an attempt is made to read a record using the new ID. If
426|* the read is not successful, the ID is assumed to be a search string, and
427|* the search subroutine is called to select an ID based on the search
428|* string. If a valid ID is returned (or if one was initially entered), the
429|* new record data is displayed. If the new ID is null, or if the search
430|* routine did not return a valid ID, a warning message is displayed and
431|* the OK indicator variable is set to FALSE. Otherwise it is set to TRUE.
432|*
433|CHECK.ID: *
434|*
435|**************************************************************************
436|*
437|* Make sure we don't have any unsaved data before changing the ID
438|*
439|GOSUB CHECK.ABANDON
440|IF NOT(OK) THEN RETURN ;* Reprompt for the ID
441|IF ID EQ '' THEN
442| OK = FALSE ;* NULL is not a valid ID!
443|END ELSE
444| *
445| *************************************************************************
446| *
447| * Check if user wants new ID
448| *
449| IF ID EQ 'N' OR ID EQ 'n' THEN
450|  * Get next sequential ID
451|  READVU ID FROM FN.DICT.CUST,'NEXT',2 THEN
452|   WRITEV ID + 1 ON FN.DICT.CUST,'NEXT',2
453|   GOSUB RESTART
454|   IDATA(1) = ID
455|  END ELSE
456|   PRINT EL:UNDREV:'Next item counter record not found!':NORMAL:BEL:
457|   INPUT ANS:
458|   PRINT EL:
459|   OK = FALSE
460|   RETURN
461|  END
462| END ELSE
463|  *
464|  *************************************************************************
465|  *
466|  * Try to read the customer record from the entered ID
467|  *
468|  GOSUB READ.RECORD
469|  IF NOT(OK) THEN
470|   *
471|   ************************************************************************
472|   *
473|   * The attempt to read a record failed - assume the ID is a search string
474|   *
475|   GOSUB HIDEPIX ;* Pictures always show on top of text, so hide before call
476|   CALL UIEX.GET.CUST.IDX(XID,ID,FN.CUST.XREF,FN.CUST)
477|   GOSUB DSPSCRN ;* Refresh the screen after index lookup
478|   *
479|   ************************************************************************
480|   *
481|   * If the user did not select an item in the search routine, reprompt
482|   *
483|   IF XID EQ '' THEN RETURN
484|   *
485|   ************************************************************************
486|   *
487|   * Try to read the customer record from the selected ID
488|   *
489|   ID = XID
490|   GOSUB READ.RECORD
491|   *
492|  END
493| END  
494|END
495|*
496|**************************************************************************
497|*
498|* If success, display the new record, otherwise show warning message
499|*
500|IF OK THEN
501| GOSUB DSPDATA ;* Display new record
502|END ELSE
503| PRINT EL:UNDREV:'Please enter a valid customer ID!':NORMAL:BEL:
504|END
505|RETURN
506|*
507|*
508|**************************************************************************
509|*
510|* The READ.RECORD subroutine reads a new customer record from the file and
511|* initializes the internal field data array (IDATA) from the record array
512|* (CUST.REC). If the record does not exist, the routine returns with the
513|* OK indicator variable set to FALSE. Otherwise OK is set to TRUE, and the
514|* CUST.ID variable is set to the new ID.
515|*
516|READ.RECORD: *
517|*
518|MATREAD CUST.REC FROM FN.CUST,ID THEN
519| CUST.ID = ID
520| IDATA(1) = CUST.ID
521| IDATA(2) = CUST.CONTACT
522| IDATA(3) = CUST.NAME
523| IDATA(4) = CUST.ADDRESS1
524| IDATA(5) = CUST.ADDRESS2
525| IDATA(6) = CUST.CITY
526| IDATA(7) = CUST.ST
527| IDATA(8) = CUST.ZIP
528| IDATA(9) = CUST.COUNTRY
529| IDATA(10) = CUST.PHONE
530| IDATA(11) = CUST.FAX
531| IDATA(12) = CUST.HISTORY
532| OK = TRUE ;* Set the SUCCESS indicator
533|END ELSE
534| OK = FALSE ;* Set the FAILURE indicator
535|END
536|RETURN
537|*
538|*
539|**************************************************************************
540|*
541|* The DELETE.RECORD subroutine confirms that the user intends to delete
542|* the current record. If the action is confirmed, the CUST.DELETE
543|* subroutine is called to perform the deletion. A separate subroutine is
544|* used to handle updating indexes, etc.
545|*
546|DELETE.RECORD: *
547|*
548|IF CUST.ID NE '' THEN
549| PRINT EL:UNDREV:'Are you sure you want to delete this customer? ':NORMAL:
550| INPUT ANS:
551| IF ANS[1,1] EQ 'Y' OR ANS[1,1] EQ 'y' THEN
552|  * Deletion has been confirmed - do the delete
553|  OK = TRUE ;* Set the SUCCESS indicator
554|  CALL UIEX.CUST.DELETE(CUST.ID,FN.CUST,FN.CUST.XREF)
555|  DONE = TRUE ;* proceed to next record
556|  GOSUB HIDEPIX ;* erase picture
557| END ELSE
558|  OK = FALSE ;* Set the FAILURE indicator
559| END
560|END
561|RETURN
562|*
563|*
564|**************************************************************************
565|*
566|* The SAVE.RECORD subroutine copies internal field data from the IDATA
567|* array to the customer record array (CUST.REC). The CUST.UPDATE
568|* subroutine is called to perform the update. A separate subroutine is
569|* used to handle updating indexes, etc.
570|*
571|SAVE.RECORD: *
572|*
573|IF IDATA(1) NE '' THEN
574| * Copy data from the internal field data array (IDATA) to the CUST.REC array
575| CUST.ID = IDATA(1)
576| CUST.CONTACT = IDATA(2)
577| CUST.NAME = IDATA(3)
578| CUST.ADDRESS1 = IDATA(4)
579| CUST.ADDRESS2 = IDATA(5)
580| CUST.CITY = IDATA(6)
581| CUST.ST = IDATA(7)
582| CUST.ZIP = IDATA(8)
583| CUST.COUNTRY = IDATA(9)
584| CUST.PHONE = IDATA(10)
585| CUST.FAX = IDATA(11)
586| CUST.HISTORY = IDATA(12)
587| * Update the file
588| CALL UIEX.CUST.UPDATE(CUST.ID,MAT CUST.REC,FN.CUST,FN.CUST.XREF)
589| OK = TRUE ;* Set the SUCCESS indicator
590|END ELSE
591| OK = FALSE ;* Set the FAILURE indicator
592|END
593|DONE = TRUE ;* proceed to next record
594|RETURN
595|*
596|*
597|**************************************************************************
598|*
599|* The RESTART subroutine prepares the internal field data array (IDATA),
600|* customer record array (CUST.REC) and ID for a new customer record.
601|*
602|RESTART: *
603|*
604|CUST.ID = ''
605|MAT CUST.REC = ''
606|MAT IDATA = ''
607|ACTIVE = 0
608|RETURN
609|*
610|*
611|**************************************************************************
612|*
613|* The CHECK.CHANGED subroutine checks if any internal field data has been
614|* changed. The OK indicator variable is set to FALSE if any data is
615|* changed, otherwise it is set to TRUE. The ID field is not checked, since
616|* it is appropriately handled by the CHECK.ID subroutine.
617|*
618|CHECK.CHANGED: *
619|*
620|OK = FALSE
621|IF CUST.CONTACT # IDATA(2) THEN RETURN
622|IF CUST.NAME # IDATA(3) THEN RETURN
623|IF CUST.ADDRESS1 # IDATA(4) THEN RETURN
624|IF CUST.ADDRESS2 # IDATA(5) THEN RETURN
625|IF CUST.CITY # IDATA(6) THEN RETURN
626|IF CUST.ST # IDATA(7) THEN RETURN
627|IF CUST.ZIP # IDATA(8) THEN RETURN
628|IF CUST.COUNTRY # IDATA(9) THEN RETURN
629|IF CUST.PHONE # IDATA(10) THEN RETURN
630|IF CUST.FAX # IDATA(11) THEN RETURN
631|IF CUST.HISTORY # IDATA(12) THEN RETURN
632|OK = TRUE
633|RETURN
634|*
635|*
636|**************************************************************************
637|*
638|* The CHECK.ABANDON subroutine calls CHECK.CHANGED. If any changes are
639|* found, a message is displayed and the user is prompted to abandon the
640|* changes. If there are no changes, or if the user decides to abandon
641|* changes, the OK indicator variable is set to TRUE. Otherwise it is set
642|* to FALSE.
643|*
644|CHECK.ABANDON: *
645|*
646|GOSUB CHECK.CHANGED
647|IF NOT(OK) THEN
648| PRINT EL:UNDREV:'Do you want to abandon all your changes? ':NORMAL:BEL:
649| INPUT ANS:
650| IF ANS[1,1] EQ 'Y' OR ANS[1,1] EQ 'y' THEN OK = 1
651| PRINT EL:
652|END
653|RETURN
654|*
655|*
656|**************************************************************************
657|*
658|* The DSPSCRN subroutine is used to refresh the entire screen.
659|*
660|DSPSCRN: *
661|*
662|* Clear the screen
663|PRINT CLR:NORMAL:
664|*
665|* If running AccuTerm, display the logo
666|IF IMGFLG THEN
667| PRINT ESC:STX:'iL,':PIX.PATH:'ASE-LOGO-SMALL.JPG,65,0,12,2,0,N':CR:
668|END
669|*
670|* Display heading & labels
671|PRINT @(5,0):'Customer File Maintenance':
672|FOR XLINE = 1 TO NUMFLDS
673| LBWD = CONTROL(XLINE)<1,4>
674| LBTX = (XLINE 'L#2 ') : CONTROL(XLINE)<1,1> ;* Prepend line number to label
675| IF LBWD > 0 THEN LBTX = (LBTX : STR('.',LBWD))[1,LBWD] ;* Pad label with dots
676| PRINT @(CONTROL(XLINE)<1,2>,CONTROL(XLINE)<1,3>):LBTX:
677|NEXT XLINE
678|*
679|* Display the field data
680|GOSUB DSPDATA
681|RETURN
682|*
683|*
684|**************************************************************************
685|*
686|* The DSPDATA subroutine is used to refresh the field data for all fields.
687|*
688|DSPDATA: *
689|*
690|FOR XLINE = 1 TO NUMFLDS
691| GOSUB DSPLINE
692|NEXT XLINE
693|GOSUB SHOWPIX
694|RETURN
695|*
696|*
697|**************************************************************************
698|*
699|* The DSPLINE subroutine is used to refresh the field data for one field.
700|* The field to be refreshed is specified by the XLINE variable. If the
701|* field is active (XLINE = ACTIVE), then the field data is displayed using
702|* the REVERSE display attribute. Otherwise it is displayed using the
703|* DIMREV display attribute.
704|*
705|DSPLINE: *
706|*
707|MSK = 'L#':CONTROL(XLINE)<1,7>
708|PRINT @(CONTROL(XLINE)<1,5>,CONTROL(XLINE)<1,6>):
709|IF XLINE EQ ACTIVE THEN
710| PRINT REVERSE:
711|END ELSE
712| PRINT DIMREV:
713|END
714|PRINT IDATA(XLINE) MSK: