home *** CD-ROM | disk | FTP | other *** search
- * Program: NetGet.prg
- * Author: David Morgan
- * Version: Clipper Summer '87
- * Copyright (c) 1988 Nantucket Corp.
- *
- * Notes: Clipper UDF to demonstrate a feedback mechanism
- * for use while two or more network workstations are
- * GETting data (into memvars) for the same fields.
- * UDF mirrors other users' changes to the data being
- * edited on your screen. UDF used in VALID clause,
- * so feedback occurs field-by-field each time you
- * transition GET-to-GET.
- *
-
- orig_color = SETCOLOR()
- CLEAR
- SET PROCEDURE TO LOCKS
- SET EXCLUSIVE OFF
-
- t = 2
- l = 2
- @ 3, 0 SAY "Coordinates:"
- @ 5, 5 SAY "Top_____________________" GET t RANGE 0,23
- @ 6, 5 SAY "Left____________________" GET l RANGE 0,79
- READ
- CLEAR
-
- DECLARE files[ADIR("*.DBF")]
- ADIR("*.DBF",files)
- @ 0,0 TO 10,14
- @ 16,1 SAY "Select a file, or ESC to default to NG_Exmpl.dbf"
- file = ACHOICE(1,1,9,13,files)
- IF file = 0
- USE ng_exmpl
- DECLARE fname[5]
- fname[1] = "st_abbrev"
- fname[2] = "st_name"
- fname[3] = "st_capital"
- fname[4] = "st_bird"
- fname[5] = "st_flower"
- DECLARE cues[5]
- cues[1] = "Here's the abbreviation"
- cues[2] = "Here's the state"
- cues[3] = "Here's the capital city"
- cues[4] = "And the state bird"
- cues[5] = "... and you write the prompts!"
- ELSE
- USE (files[file])
- DECLARE fname[FCOUNT()]
- AFIELDS(fname)
- cues = ''
- END
- CLEAR
- DO WHILE net_get(t,l,fname,cues) .AND. LASTKEY() # 27
- ENDDO
- SETCOLOR(orig_color)
- CLEAR
- *================================================================
-
- FUNCTION Net_get
- *
- *
- PARAMETERS start_row, start_col, names, promts
- PRIVATE dimension, p_count
- p_count = PCOUNT()
- dimension = LEN(names)
- PRIVATE back_color, border_color, f, get_col, get_color, ;
- get_width, old_color, say_color, unsel_color
- PRIVATE current[dimension], last_seen[dimension], ;
- proposed[dimension], they_altered[dimension]
- IF IIF( p_count = 3, ;
- .T., ;
- TYPE("promts")#"A")
-
- PRIVATE promts[dimension]
- ACOPY(names,promts)
- ELSE
- IF TYPE("names") # "A" .OR. TYPE("promts") # "A"
- RETURN (.F.)
- END
- IF LEN(promts) # dimension
- RETURN (.F.)
- END
- END
- max_promt = LEN(promts[1])
- FOR f = 2 TO dimension
- max_promt = MAX(LEN(promts[f]),max_promt)
- NEXT
- get_col = start_col + max_promt + 3
- IF get_col + maxn() > 79
- RETURN(.F.)
- END
- get_width = LTRIM(STR(80-(get_col+2)))
-
- REC_LOCK(0)
- scatter(current,names)
- UNLOCK
- ACOPY(current,last_seen)
- ACOPY(current,proposed)
- AFILL(they_altered,.F.)
- DO Store_colors
-
- DO Nget_SAYs()
- DO Nget_GETs()
- READ
- RETURN (.T.)
- *----------------------------------------------------------------
-
- FUNCTION Ed_sens
- *
- *
- PARAMETERS gf
- PRIVATE I_changed, mvar, they_changed, winbuff
- STORE .F. TO I_changed, they_changed
-
- *** Check for changes by me ***
- I_changed = .NOT.(last_seen[gf] == proposed[gf])
-
- *** Check for changes by others ***
- REC_LOCK(0)
- scatter(current,names) && Do a fresh take on the disk.
- they_changed = .NOT.(asame(current,last_seen))
-
- IF I_changed
- *** write immediately then unlock
- mvar = names[gf]
- REPLACE &mvar. WITH proposed[gf]
- COMMIT
- UNLOCK && Unlock immediately once writing is over.
- current[gf] = proposed[gf] && Keep current[] abreast.
- last_seen[gf] = proposed[gf] && Keep last_seen[] abreast.
- they_altered[gf] = .F. && Suppress display of their changes
- && to this field below, if any.
- SETCOLOR(get_color + get_color + border_color + back_color + ;
- unsel_color)
- resay(proposed,gf)
- SETCOLOR(old_color)
- END
- UNLOCK
-
- IF they_changed
- winbuff = SAVESCREEN(0,0,1,79)
- SET CURSOR OFF
- SETCOLOR(get_color + "*" + get_color + border_color + ;
- back_color + unsel_color)
- @ 0,0 SAY ' ==> Field(s) have been changed by another...'+ ;
- 'press any key to continue. <== '
- FOR f = 1 TO dimension
- IF they_altered[f]
- resay(current,f)
- END
- NEXT
- INKEY(0)
- SET CURSOR ON
- RESTSCREEN(0,0,1,79,winbuff)
- SETCOLOR(get_color + get_color + border_color + back_color + ;
- unsel_color)
- FOR f = 1 TO dimension
- IF they_altered[f]
- resay(current,f)
- END
- NEXT
- SETCOLOR(old_color)
- ACOPY(current,last_seen) && Bring "last_seen" up to date.
- ACOPY(current,proposed)
- AFILL(they_altered,.F.)
- END
- RETURN (.T.)
- *----------------------------------------------------------------
-
- FUNCTION Asame
- *
- * Determine whether two arrays have identical contents.
- * Along the way, track which individual elements do not.
- * Initialize they_altered[] to all .F. before calling.
- *
- PARAMETERS array1,array2
- PRIVATE f, g
- FOR f = 1 TO dimension
- IF .NOT.(array1[f]==array2[f])
- they_altered[f] = .T.
- FOR g = f+1 TO dimension
- they_altered[g] = .NOT.(array1[g]==array2[g])
- NEXT
- RETURN(.F.)
- END
- NEXT
- RETURN (.T.)
- *----------------------------------------------------------------
-
- PROCEDURE Nget_SAYs
- *
- *
- FOR f = 1 TO dimension
- @ start_row+f-1,start_col SAY promts[f]+': '
- NEXT
- RETURN
- *----------------------------------------------------------------
-
- PROCEDURE Nget_GETs
- *
- *
- FOR f = 1 TO dimension
- f_str = ltrim(str(f))
-
- IF IIF( TYPE("proposed[f]") = 'C', ;
- LEN(proposed[f]) > VAL(get_width), ;
- .F. )
- @ start_row+f-1,get_col GET proposed[f] ;
- PICTURE '@S&get_width.';
- VALID ed_sens(&f_str.)
- ELSE
- ** Summer '87 trick follows: submit f to ed_sens laundered
- ** thru macro &f_str. to allow READ to distinguish one GET
- ** from the next by subscript.
- @ start_row+f-1,get_col GET proposed[f] ;
- VALID ed_sens(&f_str.)
- END
- NEXT
- RETURN
- *----------------------------------------------------------------
-
- PROCEDURE Store_colors
- old_color = SETCOLOR()
- say_color = SUBSTR(old_color,1,AT(",",old_color)-1)
- old_color = SUBSTR(old_color,AT(",",old_color)+1)
- get_color = SUBSTR(old_color,1,AT(",",old_color)-1)
- old_color = SUBSTR(old_color,AT(",",old_color)+1)
- border_color = SUBSTR(old_color,1,AT(",",old_color)-1)
- old_color = SUBSTR(old_color,AT(",",old_color)+1)
- back_color = SUBSTR(old_color,1,AT(",",old_color)-1)
- unsel_color = SUBSTR(old_color,AT(",",old_color)+1)
- old_color = SETCOLOR()
- RETURN
- *----------------------------------------------------------------
-
- FUNCTION Scatter
- *
- * Make array image of a record.
- * Requires successful RLOCK() before calling.
- *
- PARAMETERS c_array,f_array && contents array and fields array
- PRIVATE f, mvar
- FOR f = 1 TO LEN(f_array)
- mvar = f_array[f]
- c_array[f] = &mvar.
- NEXT
- RETURN (.T.)
- *----------------------------------------------------------------
-
- FUNCTION Maxn
- * Return length of longest numeric field in current DBF.
- PRIVATE f, i, fieldt[FCOUNT()], fieldw[FCOUNT()], mn
- AFIELDS('',fieldt,fieldw)
- STORE 0 TO i, mn
- f = FCOUNT()
- DO WHILE i < f
- i = ASCAN(fieldt,"N",i+1)
- IF i = 0
- EXIT
- END
- mn = MAX(fieldw[i],mn)
- END
- RETURN(mn)
- *----------------------------------------------------------------
-
- FUNCTION Resay
- PARAMETERS array, ff
- IF TYPE("array[ff]") = 'C'
- @ start_row+ff-1,get_col SAY SUBSTR(array[ff],1,VAL(get_width))
- ELSE
- @ start_row+ff-1,get_col SAY array[ff]
- END
- RETURN (.T.)
- *================================================================