; $Id: xvaredit.pro,v 1.5 1997/01/15 03:11:50 ali Exp $ ; ; Copyright (c) 1991-1997, Research Systems, Inc. All rights reserved. ; Unauthorized reproduction prohibited. ;+ ; NAME: ; XVAREDIT ; PURPOSE: ; This routine provides an editor for any IDL variable. ; CATEGORY: ; Widgets ; CALLING SEQUENCE: ; XVAREDIT, VAR ; INPUTS: ; VAR = The variable that is to be edited. ; KEYWORD PARAMETERS: ; NAME = The NAME of the variable. This keyword is overwritten with the ; structure name if the variable is a structure. ; GROUP = The widget ID of the widget that calls XVarEdit. When this ; ID is specified, a death of the caller results in a death of ; XVarEdit. ; X_SCROLL_SIZE = The X_SCROLL_SIZE keyword allows you to set ; the width of the scrolling viewport in columns. ; Default is 4. ; Y_SCROLL_SIZE = The Y_SCROLL_SIZE keyword allows you to set ; the height of the scrolling viewport in rows. ; Default is 4. ; OUTPUTS: ; VAR= The variable that has been edited, or the original when the user ; selects the "Cancel" button in the editor. ; COMMON BLOCKS: ; None. ; SIDE EFFECTS: ; Initiates the XManager if it is not already running. ; RESTRICTIONS: ; None known. ; PROCEDURE: ; Create and register the widget and then exit. ; If the user selects "accept", the values in the editor are written ; to the variable passed in, otherwise, they are ignored. ; MODIFICATION HISTORY: ; Written by: Steve Richards, February, 1991 ; Modified: September 96, LP - rewritten with TABLE widget ;- ;------------------------------------------------------------------------------ ; procedure XVarEdit_event ;------------------------------------------------------------------------------ ; This procedure processes the events being sent by the XManager. ;------------------------------------------------------------------------------ PRO XVarEdit_event, event WIDGET_CONTROL, event.id, GET_UVALUE = whichevent IF N_ELEMENTS(whichevent) EQ 0 THEN RETURN IF whichevent NE "THEBUTTON" THEN RETURN CASE event.value OF 0: BEGIN ;the user chose the WIDGET_CONTROL, event.top, /DESTROY ;return the initial END ;variable 1: BEGIN ;the user chose accept WIDGET_CONTROL, event.top, GET_UVALUE = pEval (*pEval).modified = 1 IF (*pEval).usetable THEN BEGIN WIDGET_CONTROL, (*pEval).table, GET_VALUE = var (*pEval).var = TEMPORARY(var) ENDIF ELSE BEGIN i = 0 ;so go ahead and modify the variable WIDGET_CONTROL, (*pEval).table, GET_VALUE = var WHILE(i LT N_ELEMENTS((*pEval).entries))DO BEGIN assign = '=' IF((*pEval).entries[i].type EQ 6)THEN assign = '=COMPLEX' CATCH, errorStatus IF errorStatus EQ 0 THEN $ status = EXECUTE("(*pEval)." + (*pEval).entries[i].name + $ assign + var[i]) $ ELSE $ tmp = DIALOG_MESSAGE([ 'XVarEdit conversion error:', $ '', !err_string ] , /error) CATCH, /CANCEL i = i + 1 ENDWHILE ENDELSE WIDGET_CONTROL, event.top, /DESTROY ;once the variables END ;have been retrieved, ;the widget heiarchy ELSE: ;can be destroyed ENDCASE END ;============= end of XVarEdit event handling routine task ============= ;------------------------------------------------------------------------------ ; procedure AddEditEntry ;------------------------------------------------------------------------------ ; This procedure adds an entry to the list that contains the variables names ; and the widget id for the edit field corresponding to the variable name. ;------------------------------------------------------------------------------ PRO AddEditEntry, entries, nentries, thename, thetype, value newelt = {entstr, name:thename, $ ;first create a record value:value, $ ;and then type:thetype} ;just create a list numents = N_ELEMENTS(entries) ;with one more element IF(NOT(KEYWORD_SET(entries))) THEN BEGIN entries = newelt ;and replace the old nentries = 1 ENDIF ELSE BEGIN ;one IF (numents LE nentries) THEN BEGIN newentries = REPLICATE(newelt, numents + 100) newentries[0:numents - 1] = entries nentries = numents + 1 newentries[numents] = newelt entries = newentries ENDIF ELSE BEGIN entries[nentries] = newelt nentries = nentries + 1 ENDELSE ENDELSE END ;============== end of XVarEdit event handling routine task =============== ;------------------------------------------------------------------------------ ; procedure XvarEditField ;------------------------------------------------------------------------------ ; This routine is used to create the widget or widgets needed for a given ; variable type. It could call itself recursively if the variable was itself ; a structure comprised of other IDL variables. ;------------------------------------------------------------------------------ FUNCTION XvarEditField, base, val, usetable, entries, nentries, NAME = NAME, $ RECNAME = RECNAME, $ X_SCROLL_SIZE = X_SCROLL_SIZE, $ Y_SCROLL_SIZE = Y_SCROLL_SIZE FORWARD_FUNCTION XvarEditField typarr = ["Undefined", "Byte", "Integer", $ ;an array of names of "Longword Integer", "Floating Point", $ ;each type "Double Precision Floating", $ "Complex Floating Point", $ "String", "Structure"] varsize = size(val) ;determine the size and vardims = N_ELEMENTS(varsize) - 2 ;type of the variable type = varsize[vardims] numelements = varsize[vardims + 1] usetable = 0 IF (NOT(KEYWORD_SET(RECNAME)) AND $ (varsize[0] EQ 1 OR varsize[0] EQ 2)) THEN BEGIN IF(type EQ 8) THEN BEGIN FOR i = 0, N_TAGS(val) - 1 DO BEGIN strsize = size(val.(i)) strdims = N_ELEMENTS(strsize) - 2 IF strsize[strdims] EQ 8 OR $ strsize[strdims + 1] NE varsize[vardims + 1] THEN $ Goto, Cplx_Struct ENDFOR usetable = 1 ENDIF ELSE BEGIN usetable = 1 ENDELSE ENDIF Cplx_Struct: recurse = KEYWORD_SET(RECNAME) IF (NOT recurse) THEN $ abase = WIDGET_BASE(base, /FRAME, /COLUMN, XPAD = 8, YPAD = 8) IF(numelements GT 1) THEN BEGIN ;if the variable is an suffix = " Array(" ;array, then say so and FOR j = 1, varsize[0] DO BEGIN ;show the array suffix = suffix + strtrim(varsize[j], 2) ;dimensions. IF j NE varsize[0] THEN suffix = suffix + ", " ENDFOR suffix = suffix + ")" ENDIF ELSE suffix = "" IF(type EQ 8) THEN NAME = TAG_NAMES(val, /STRUCTURE) ;if the variable is a ;structure, use its ;name ;build up the name of variable with the type in parentheses IF(NOT recurse) THEN BEGIN IF(KEYWORD_SET(NAME)) THEN $ lbl = WIDGET_LABEL(abase, $ VALUE = NAME + " (" + typarr[type] + suffix + ")") $ ELSE lbl = WIDGET_LABEL(abase, $ value = typarr[type] + suffix) ENDIF IF(NOT(KEYWORD_SET(RECNAME))) THEN RECNAME = "var" ;establish the name ;if not being called ;recursively IF(N_ELEMENTS(X_SCROLL_SIZE) EQ 0) THEN $ XSCROLL_SIZE = 4 ELSE XSCROLL_SIZE = X_SCROLL_SIZE IF(N_ELEMENTS(Y_SCROLL_SIZE) EQ 0) THEN $ YSCROLL_SIZE = 4 ELSE YSCROLL_SIZE = Y_SCROLL_SIZE IF (usetable) THEN BEGIN IF(type EQ 8) THEN BEGIN table = WIDGET_TABLE(abase, value = val, $ COLUMN_LABELS = TAG_NAMES(val), $ /RESIZEABLE_COLUMNS, /EDIT, $ X_SCROLL_SIZE = XSCROLL_SIZE, $ Y_SCROLL_SIZE = YSCROLL_SIZE) ENDIF ELSE BEGIN table = WIDGET_TABLE(abase, value = val, $ /RESIZEABLE_COLUMNS, /EDIT, $ X_SCROLL_SIZE = XSCROLL_SIZE, $ Y_SCROLL_SIZE = YSCROLL_SIZE) ENDELSE RETURN, table ENDIF IF(varsize[0] GT 1) THEN BEGIN moduli = LONARR(varsize[0]-1) + 1 FOR i = varsize[0], 2,-1 DO BEGIN FOR j = 1,i-1 DO $ moduli[i - 2] = moduli[i - 2] * varsize[j] ENDFOR ENDIF FOR element = 0, numelements - 1 DO BEGIN ;for each array element IF(numelements NE 1) THEN BEGIN ;use array subscripting indexname = "(" ;if variable is an indexname = indexname + $ strtrim(element mod varsize[1],2) IF(varsize[0] GT 1) THEN BEGIN indexarr = lonarr(varsize[0] - 1) flatindex = element FOR i = varsize[0] - 2, 0, -1 DO BEGIN indexarr[i] = flatindex / moduli[i] flatindex = flatindex mod moduli[i] ENDFOR FOR i = 0, varsize[0] - 2 DO $ indexname = indexname + ", " + $ strtrim(indexarr[i], 2) ENDIF indexname = indexname + ")" thename = RECNAME + indexname ENDIF ELSE BEGIN thename = RECNAME ENDELSE ;depending on the type, build a string variable with proper formatting CASE type OF 0: thevalue = "Undefined Variable" ;Undefined 1: thevalue = string(val[element], $ ;Byte FORMAT = '(I3)') 7: thevalue = val[element] ;String 8: BEGIN ;Structure tags = TAG_NAMES(val[element]) FOR i = 0, N_ELEMENTS(tags) - 1 DO BEGIN error = EXECUTE("fieldvalue = val[element]." + tags[i]) fldsize = size(fieldvalue) flddims = N_ELEMENTS(fldsize) - 2 id = XvarEditField(abase, fieldvalue, usetable, entries, nentries, $ NAME = tags[i], $ RECNAME = thename + "." + tags[i], $ X_SCROLL_SIZE = XSCROLL_SIZE, $ Y_SCROLL_SIZE = YSCROLL_SIZE) ENDFOR END ELSE: thevalue = strtrim(val[element], 2) ENDCASE IF(type NE 8) THEN BEGIN ;here the actual widget AddEditEntry, entries, nentries, thename, type, thevalue END ENDFOR table = 0 IF (NOT recurse) THEN BEGIN IF (N_ELEMENTS(entries.value) GT 1) THEN BEGIN table = WIDGET_TABLE(abase, value = TRANSPOSE(entries.value), $ ROW_LABELS = TRANSPOSE(entries.name), $ COLUMN_LABELS = '', $ /RESIZEABLE_COLUMNS, /EDIT, $ COLUMN_WIDTHS=150, $ Y_SCROLL_SIZE = YSCROLL_SIZE) ENDIF ELSE BEGIN table = WIDGET_TABLE(abase, value = [entries.value], $ ROW_LABELS = [entries.name], $ COLUMN_LABELS = '', $ /RESIZEABLE_COLUMNS, /EDIT, $ COLUMN_WIDTHS=150, $ Y_SCROLL_SIZE = YSCROLL_SIZE) ENDELSE ENDIF return, table END ;============= end of XVarEdit event handling routine task ============= ;------------------------------------------------------------------------------ ; procedure XVarEdit ;------------------------------------------------------------------------------ ; this is the actual routine that is called. It builds up the variable editing ; fields by calling other support routines and then registers the widget ; heiarchy with the XManager. Notice that the widget is registered as a MODAL ; widget so it will desensitize all other current widgets until it is done. ;------------------------------------------------------------------------------ PRO XVarEdit, var, GROUP = GROUP, NAME = NAME, $ X_SCROLL_SIZE = X_SCROLL_SIZE, Y_SCROLL_SIZE = Y_SCROLL_SIZE if(n_params() ne 1) THEN $ MESSAGE, "Must have one parameter" XVarEditbase = WIDGET_BASE(TITLE = "XVarEdit", $ ;create the main base /COLUMN) menu = Cw_Bgroup(XVarEditbase, ['Cancel', 'Accept'], /ROW, UVALUE="THEBUTTON") entries = 0 nentries = 0 table = XvarEditField(XVarEditbase, var, usetable, entries, nentries, $ NAME = NAME, X_SCROLL_SIZE = X_SCROLL_SIZE, $ Y_SCROLL_SIZE = Y_SCROLL_SIZE) XVarEditStat = {var:var, $ entries:entries, $ modified:0, $ table: table, $ usetable: usetable} pXVarEditStat = PTR_NEW(XVarEditStat, /NO_COPY) WIDGET_CONTROL, XVarEditbase, SET_UVALUE=pXVarEditStat WIDGET_CONTROL, XVarEditbase, /REALIZE XManager, "XVarEdit", XVarEditbase, $ ;register the widgets GROUP_LEADER = GROUP ;and pass through the ;group leader if this ;routine is to be ;called from some group ;leader. ; Get the return value IF ((*pXVarEditStat).modified) THEN var = (*pXVarEditStat).var PTR_FREE, pXVarEditStat END ;================== end of XVarEdit main routine =======================