;+
; Project     : SOHO - CDS     
;                   
; Name        : PICKFITS
;               
; Purpose     : Browse/search lfitslist.txt to find CDS/SUMER fits files.
;               
; Explanation : CDS (SUMER: see below) fits file names don't tell you much
;               about their content, but there may be an lfitslist.txt file
;               generated by CFITSLIST with more information on each file in
;               your home directory ($HOME) or in the $CDS_FITS_DATA
;               directory.
;
;               This program enables the user to search the lfitslist.txt file
;               for the files of interest, and an to allow users to simply
;               click on a line with an interesting fits file to read it in
;               through readcdsfits.
;
;               If no parameter is supplied for storage of the QLDS, a
;               version of DSP_MENU will be started for each selected fits 
;               file. The data can be retrieved by the
;
;               IDL> @recover
;
;               procedure after termination of all widget applications.
;
;               lfitslist.txt contains a lot of information taken from the
;               fits files, but not all the information has to be displayed at
;               the same time.  The user may choose what information should be
;               displayed/searched by setting the environment variable
;               "CDS_PICKFITS_FIELDS". This environment variable should
;               be a string consisting of a series of FIELD names with
;               a colon as a separator. The possible field names are 
;               shown in the field selection menu 
;
;               It is also possible for the user to change the list of fields
;               to be displayed by (de)selecting from the FIELD selection
;               menu. Doing so will alter the contents of
;               "CDS_PICKFITS_FIELDS".
;
;               The search is done by specifying a search string, either
;               through the FIND keyword, or interactively.  The search string
;               is a sequence of texts separated by the operators '&','|', and
;               '$'.
;
;               The search string "active&nis" contains the search texts
;               "active" and "nis", and will select for display only those
;               lines in lfitslist.txt that contain these texts.
;
;               "active|nis" will select lines with either "active"
;               or "nis".
;
;               "16/03|17/03$NIS" will select lines with (EITHER "16/03" OR
;               "17/03") AND "nis".
;               
;               Parentheses are not allowed in the search, but with one AND
;               operator with high precedence (&) and one with low precedence
;               ($), there should be little need for them.
;               
;               SUMER OPTION
;
;               Although originally written to cope with CDS fits file
;               lists, pickfits will also work with SUMER fits file lists
;               generated by SFITSLIST, by setting the /SUMER keyword.
;
;               In that case, pickfits looks for the file sfitslist.txt in
;               $HOME,$SUM_FITS_DATA (or sys$login,$sum_fits_data for
;               VMS). The FIELDS to be displayed will be taken from the
;               environment variable SUM_PICKFITS_FIELDS, and altering the
;               selection of fields in the FIELDS menu will set the value of
;               this environment variable.
;
;               Reading SUMER fits files is done quite differently from
;               reading CDS fits files, but the two methods are now converging
;               somewhat. When the SUMER option is set, pickfits expects to
;               have *two* ouput parameters, index and data. Pickfits calls
;               rd_sumer,filename,index,data to read SUMER fits files, and
;               returns the results in the two pickfits parameters.
;
; Use         : PICKFITS [,QLDS]
;               PICKFITS,INDEX,DATA ;; For SUMER mode
;    
; Inputs      : QLDS : A named variable that will contain
;                      the selected fits file on exit. Not used
;                      with the /SUMER option.
;                      
;                      If a parameter is not given, it is assumed that
;                      the user wants to start a copy of dsp_menu for
;                      each selected fits file.
;
; Opt. Inputs : 
;               
; Outputs     : QLDS contains the result of readcdsfits for the
;               selected fits file.
;               
; Opt. Outputs: None.
;               
; Keywords    : FIND : An initial search string. May contain logical
;                      operators.
;
;               TEST_FILE : Set to anything to make PICKFITS test whether it
;                           can find a list of fits files. Pickfits will
;                           return promptly with TEST_FILE =/= '' if a file
;                           has been found.
; 
;               FIRST, 
;               LAST : Search texts (simple, no operators) that define
;                      the first and last entry to be displayed in the list.
;
;               NEWFILE : Force reading of the lfitslist.txt file (don't use
;                         any cached version). This is seldom necessary to
;                         specify, since the file will be read from disk
;                         whenever the size changes.
;
;               DIR : A string with the name of the directory where the
;                     lfitslist.txt file is located. Default value is
;                     "$CDS_FITS_DATA" (or "$SUM_FITS_DATA" if the /SUMER
;                     flag is set), and then "$HOME"
;
;               SUMER : Set to specify browsing of sumer data. 
;
;               GROUP : Group leader - the death of the group leader causes
;                       the death of pickfits
;
;               MODAL : Modal, use whenever you need data returned to the
;                       caller.
;               
; Calls       : DEFAULT, FILE_EXIST(), FIND_WITH_DEF()
;               GET_DFONT(), HANDLE_CREATE(), PARCHECK, RD_ASCII(),
;               READCDSFITS(), SETENV, STRPAD(), TEXT_MATCH(), TRIM(),
;               TYP()
;
; Common      : PICKFITS_RD_FILE_CACHE: Contains the ascii file cache.
;
;               PICKFITS_PRIVATE: Contains the processed lists, some
;                                 widget_id's etc.
;               
; Restrictions: The program expects to find a file named "lfitslist.txt",
;               or "sfitslist.txt" for SUMER, in $HOME (sys$login) or
;               $CDS_FITS_DATA or $SUM_FITS_DATA or the directory
;               specified through the DIR keyword.
;
;               For the moment the text print option is not VMS-compatible.
;               The SUMER option is not very well tested.
;               
; Side effects: Alters the environment variables {SUM|CDS}_PICKFITS_FIELDS
;               
; Category    : CDS_Utility
;               
; Prev. Hist. : 
;
; Written     : Stein Vidar H. Haugan, UiO, 22 March 1996
;               
; Modified    : Version 4, 29 March 1996
;                          Changed HI/LOW to FIRSTTEXT/LASTTEXT.
;               Version 5, 18 April 1996
;                          Changed file format to a "generic" type,
;                          added use of CDS_PICKFITS_FIELDS to control
;                          what fields to include. "fitslist" -> "lfitslist".
;               Version 6, 22 April 1996
;                          Changed handling of returns from get_dfont.
;                          lfitslist.txt file is read when the size changes.
;                          Using find_with_def instead of concat_dir
;                          when locating the lfitslist.txt file due to
;                          Bill's multi-path announcement.
;               Version 7, 29 April 1996
;                          Tested SUMER option, added support for 
;                          both SUM_PICKFITS_FIELDS and CDS_PICKFITS_FIELDS.
;                          Even tested it does work on VMS.
;                          Dropping out empty columns in the display.
;               Version 8, 3 May 1996
;                          Added possibility for starting multiple
;                          DSP_MENUs. Almost sensible recovery of QLDS'es.
;                          Some odd segmentation faults experienced.
;               Version 9, 18 June 1996
;                          Made not finding the list file print error and
;                          return, instead of dumping. Added keyword group
;                          that avoids modal operation, and changed the way
;                          recovery of displayed data is handled.
;               Version 10, 20 June 1996
;                          Using XREGISTERED to avoid more than one copy.
;               Version 11, 6 August 1996
;                          Modified SUMER mode to use rd_sumer, added modal
;                          keyword.
;               Version 12, 3 October 1996
;                          Added TEST_FILE option.
;               Version 13, 12 May 1997
;                          Removed .fits extension added to file name, letting
;                          readcdsfits take care of it (to find compressed
;                          files). Testing for errors returned by readcdsfits.
;               Version 14, 5 June 1997
;                          Added /NOKEEP switch in dsp_menu to counter IDLv5
;                          change in widget handling.
;               Version 15, 4 August 1997
;                          Renamed STATUS=>ERRMSG keyword in readcdsfits.
;               Version 16, WTT, 23-Jun-2021, change () to []
;                          
; Version     : 16, 23-Jun-2021
;-            

FUNCTION pickfits_rd_file,file,new=new,columns=name,control=control
  ;; Text cache
  COMMON pickfits_rd_file_cache,filnam,text,filesize
  COMMON pickfits_private,ilist,uilist,list,list_wid,headtext,first,last, $
     findt,pickf_fields,menu,menulock
  
  do_read = 0
  
  IF N_PARAMS() EQ 1 THEN begin
     IF N_ELEMENTS(filnam) EQ 0 THEN do_read = 1 $
     ELSE IF (filnam NE file) OR KEYWORD_SET(new) THEN do_read = 1
     
     ;; If we are NOT going to read it, we'll check the filesize
     ;; (and read the file anyway if it has changed size).
     ;; If we are going to read it, we need to update filesize
     
     OPENR,lun,file,error=error,/GET_LUN
     IF error EQ 0 THEN BEGIN
        fst = fstat(lun)
        CLOSE,lun
        FREE_LUN,lun
        IF (NOT do_read) AND N_ELEMENTS(filesize) EQ 1 THEN $
           IF filesize NE fst.size THEN do_read = 1
        filesize = fst.size
     END
     
  END ELSE BEGIN
     IF N_ELEMENTS(filnam) EQ 0 THEN  $
        MESSAGE,"Cannot reinterpret file, cause I haven't read one yet!"
     file = filnam
  END
        
  IF do_read THEN BEGIN
     IF NOT file_exist(file) THEN RETURN,''
     PRINT,"Reading fits list",format='($,A)'
     text = rd_ascii(file)
     PRINT," -- finished"
     filnam = file
  END 
  
  form = str_sep(text[0],'=')
  
  IF N_ELEMENTS(form) MOD 3 NE 0 THEN  $
     MESSAGE,"Error in lfitslist.txt file form"
  
  Nent = N_ELEMENTS(form)/3
  form = REFORM(form[0:3*Nent-1],3,Nent)
  name = form[0,*]
  head = form[1,*]
  length = FIX(form[2,*])
  pos = length
  pos[0] = 0
  FOR i = 0,Nent-1 DO BEGIN
     IF i GT 0 THEN pos[i] = pos[i-1] + length[i-1]
  END
  
  IF N_ELEMENTS(pickf_fields) NE 0 THEN BEGIN
     fieldsarr = str_sep(pickf_fields,':')
  END ELSE BEGIN
     fieldsarr = name
  END
  
  text0 = text[0]
  text[0] = ''
  
  FOR i = 0,N_ELEMENTS(fieldsarr)-1 DO BEGIN
     elem = (WHERE(name EQ fieldsarr[i]))[0]
     IF elem EQ -1 THEN  $
        MESSAGE,"Cannot include field " + fieldsarr[i],/continue $
     ELSE BEGIN
        IF i EQ 0 THEN BEGIN
           ;; This is the file name
           tx = STRMID(text,pos[elem],length[elem])
           form = strpad(head[elem],length[elem],/after)
           tx[0] = ''
        END ELSE BEGIN
           el = STRMID(text,pos[elem],length[elem])
           mx = MAX(STRLEN(STRTRIM(el)))+1
           IF mx GT 1 THEN BEGIN
              mx = mx > ((STRLEN(head[elem])+1) < length[elem])
              tx = tx + STRMID(text,pos[elem],mx)
              form = form + strpad(head[elem],mx,/after)
           END ELSE BEGIN
              MESSAGE,"Field "+fieldsarr[i]+" is empty -- dropping", $
                 /informational
           END
        END
     END
  END
  text[0] = text0
  
  tx[0] = form
  RETURN,tx
END




PRO pickfits_find
  COMMON pickfits_private,ilist,uilist,list,list_wid,headtext,first,last, $
     findt,pickf_fields,menu,menulock
  
  ;; Make sure we have well-defined values
  
  default,findt,''
  default,first,''
  default,last,''
  
  ;; They must be scalar
  
  findt = findt[0]
  first = first[0]
  last = last[0]
  
  ;; Do the search
  ix = text_match(uilist,findt,first,last)
  IF ix[0] EQ -1 THEN list = '' $
  ELSE list = ilist[ix]
END



PRO pickfits_fitsread,index,qlds
  COMMON pickfits_private,ilist,uilist,list,list_wid,headtext,first,last, $
     findt,pickf_fields,menu,menulock
  
  line = list[index]
  name = (str_sep(line,' '))[0]
  PRINT,"Reading "+name
  status = ''
  qlds = readcdsfits(name,errmsg=status)
  IF status NE '' THEN $
     message,status,/continue
END


PRO pickfits_event,ev
  COMMON pickfits_private,ilist,uilist,list,list_wid,headtext,first,last, $
     findt,pickf_fields,menu,menulock
  
  WIDGET_CONTROL,ev.id,get_uvalue=uvalue
  
  CASE uvalue OF 
     
     ;; A file was selected -- store index and die
     'SELECT': IF menu EQ 0 THEN BEGIN
        WIDGET_CONTROL,ev.top,get_uvalue=storage
        handle_value,storage,ev.index,/set
        WIDGET_CONTROL,ev.top,/destroy
     END ELSE BEGIN
        pickfits_fitsread,ev.index,qlds
        qlmgr,qlds,valid
        IF valid THEN BEGIN 
           file = (str_sep(qlds.header.filename,'.'))[0]
           menulock = menulock OR 1 ;; This locks up menu -- always start
                                   ;;; dsp_menu
           dsp_menu,qlds,/nokeep
           IF datatype(qlds) EQ 'STC' THEN BEGIN
              qlds_report,WIDGET_BASE(),qlds,/store
              IF menulock LT 2 THEN xack,"Use @recover to get back QLDS'es"
              menulock = menulock + 2
           END
        END
     END
     
     'SPAWN': IF NOT menulock THEN menu = ev.select $
     ELSE WIDGET_CONTROL,ev.id,/set_button
     
     ;; FIND text was changed -- get it, do filtering and redisplay
     'FILTER': BEGIN
        WIDGET_CONTROL,ev.id,get_value=findstring
        findt = STRUPCASE(findstring[0])
        WIDGET_CONTROL,ev.id,set_value=findt
        pickfits_find
        WIDGET_CONTROL,list_wid,set_value=list, $
           set_list_top = ((N_ELEMENTS(list)-18) > 0)
        WIDGET_CONTROL,ev.id,/input_focus
        WIDGET_CONTROL,ev.id,set_text_select=ev.offset ;STRLEN(findstring[0])
     END
     
     ;; FIRST text changed -- get it, do filtering and redisplay
     'FIRST': BEGIN
        WIDGET_CONTROL,ev.id,get_value=first
        first = STRUPCASE(first[0])
        pickfits_find
        WIDGET_CONTROL,list_wid,set_value=list, $
           set_list_top = ((N_ELEMENTS(list)-18) > 0)
        WIDGET_CONTROL,ev.id,set_value=first
        WIDGET_CONTROL,ev.id,/input_focus
        WIDGET_CONTROL,ev.id,set_text_select=ev.offset ;STRLEN(findstring[0])
     END
     
     ;; LAST text changed -- get it, do filtering and redisplay
     'LAST': BEGIN
        WIDGET_CONTROL,ev.id,get_value=last
        last = STRUPCASE(last[0])
        pickfits_find
        WIDGET_CONTROL,ev.id,set_value=last
        WIDGET_CONTROL,list_wid,set_value=list, $
           set_list_top = ((N_ELEMENTS(list)-18) > 0)
        WIDGET_CONTROL,ev.id,/input_focus
        WIDGET_CONTROL,ev.id,set_text_select=ev.offset ;STRLEN(findstring[0])
     END
     
     ;; Print to a file.
     'PRINTF': BEGIN
        file = pickfile(file='fitslist.txt',/write)
        IF file[0] EQ '' THEN return
        OPENW,lun,file[0],/GET_LUN
        PRINTF,lun,headtext
        FOR i = 0,N_ELEMENTS(list)-1 DO BEGIN
           PRINTF,lun,list[i]
        END
        ;; PRINTF,lun,headtext
        CLOSE,lun
        FREE_LUN,lun
     END
     
     ;; Print to a printer.
     'PRINTP': BEGIN
        openw,lun,"$HOME/.pickfits_tmp",/GET_LUN
        PRINTf,lun,headtext
        FOR i=0,N_ELEMENTS(list)-1 DO BEGIN
           PRINTF,lun,list[i]
        END
        PRINTF,lun,headtext
        CLOSE,lun
        FREE_LUN,lun
        prs = "mpage -1 -W"+trim(MAX(STRLEN(list)))
        prn = getenv("PSLASER")
        IF prn EQ '' THEN prn = getenv("PRINTER")
        
        prs = prs + ' -P'+prn+" "+getenv("HOME")+'/.pickfits_tmp'
        PRINT,prs
        spawn,prs
        spawn,"rm $HOME/.pickfits_tmp"
     END
     
     ;; Abort 
     'QUIT': BEGIN
        WIDGET_CONTROL,ev.top,/destroy
     END
     
     ;; FIELD selection done. Acknowledge, reinterpret lfitslist.txt
     ;; and redisplay (with new headers)
     ;;
     ELSE: IF STRMID(uvalue,0,1) EQ '+' THEN BEGIN
        ;; May take some time
        WIDGET_CONTROL,/hourglass
        newvalue = '+'+STRMID(uvalue,2,1)+STRMID(uvalue,1,1)
        WIDGET_CONTROL,ev.id,set_uvalue=newvalue
        IF STRMID(newvalue,1,1) EQ '+' THEN WIDGET_CONTROL,ev.id,/set_button
        selection = WIDGET_INFO(WIDGET_INFO(ev.id,/parent),/parent)
        WIDGET_CONTROL,selection,get_uvalue=HEAD
        pickf_fields = 'FILENAME'
        FOR i=1,N_ELEMENTS(head.fieldbutton)-1 DO BEGIN
           WIDGET_CONTROL,head.fieldbutton[i],get_uvalue=uval
           IF STRMID(uval,1,1) EQ '+' THEN  $
              pickf_fields = pickf_fields + ':' + head.allfields[i]
        END
        SETENV,head.control+'='+pickf_fields
        list = pickfits_rd_file()
        headtext = list[0]
        ilist = list[1:*]
        uilist = STRUPCASE(ilist)
        pickfits_find
        WIDGET_CONTROL,list_wid,set_value=list,  $
           set_list_top=((N_ELEMENTS(list)-18) > 0)
        WIDGET_CONTROL,head.head1,set_value=headtext
        WIDGET_CONTROL,head.head2,set_value=headtext
     END
  ENDCASE 
END


FUNCTION findfont,sizes
  
  families = ["times","courier","helvetica","new century schoolbook","*"]
  
  ufont = ['']
  FOR i = 0,N_ELEMENTS(sizes)-1 DO begin
     ufont = '-*-'+families+'-medium-r-normal--*-'+trim(sizes[i])+'-*'
     dfont = get_dfont(ufont)
     IF dfont[0] NE '' THEN RETURN,dfont[0]
  END
  
  RETURN,''
END



PRO pickfits,qlds,sumdata,first=firstt,last=lastt,find=find,dir=dir, $
             sumer=sumer, modal=modal, test_file=test_file,$
             newfile=newfile,group=group
  
  COMMON pickfits_private,ilist,uilist,list,list_wid,headtext,first,last, $
     findt,pickf_fields,menu,menulock
  
  ON_ERROR,2
  
  IF xregistered('PICKFITS') NE 0 THEN RETURN
  
  debug = 0
  vms = !version.os EQ 'vms'
  IF NOT vms THEN $
     dummy = execute("debug=!debug") ; To cope without !debug
  IF debug NE 0 THEN ON_ERROR,0
  
  default,group,0
  default,sumer,0
  
  menu = 0
  menulock = 0
  
  IF NOT KEYWORD_SET(sumer) AND vms AND N_PARAMS() EQ 2 THEN BEGIN
     sumer = 1
     PRINT,"Assuming SUMER mode"
  END
  
  IF sumer THEN menu = 0 ELSE BEGIN
     IF N_PARAMS() EQ 0 THEN BEGIN
        menu = 1
        menulock = 1
     END
  END
  
  IF sumer AND N_PARAMS() LT 2 THEN BEGIN
     MESSAGE,"SUMER mode usage:",/continue
     MESSAGE,"PICKFITS,INDEX,DATA"
  END
  
  IF sumer THEN default,modal,1 $
  ELSE          default,modal,menu EQ 0
  
  IF vms THEN home = 'sys$login' $
  ELSE        home = '$HOME'
  
  IF KEYWORD_SET(sumer) THEN BEGIN
     default,dir,HOME + ",$SUM_FITS_DATA"
     control = "SUM_PICKFITS_FIELDS"
     FIELDS_DEF = "FILENAME:POINTING:WAVELNTH:OBS_SEQ:OBJECT:RASTYPE"
     fname = "sfitslist.txt"
  END ELSE BEGIN
     default,dir,HOME + ",$CDS_FITS_DATA"
     control = "CDS_PICKFITS_FIELDS"
     FIELDS_DEF = 'FILENAME:DETECTOR:DATE:TIME:OBS_PROG:TITLE:SCI_OBJ'
     fname = "lfitslist.txt"
  END
  
  pickf_fields = getenv(control)
  
  IF pickf_fields EQ '' OR pickf_fields EQ ' ' OR $
     STRPOS(pickf_fields,'FILENAME') NE 0 THEN BEGIN
     pickf_fields = FIELDS_DEF
     SETENV,control+"="+pickf_fields
  END
  
  file = find_with_def(fname,dir)
  
  IF file EQ '' THEN BEGIN
     IF N_elements(test_file) NE 0 THEN test_file = '' $
     ELSE MESSAGE,"Cannot find '"+fname+"' file",/continue
     RETURN
  END
  
  IF N_elements(test_file) NE 0 THEN BEGIN
     test_file = file
     return
  END
  
  list = pickfits_rd_file(file,new = KEYWORD_SET(newfile),columns=allfields)
  
  headtext = list[0]
  ilist = list[1:*]
  uilist = STRUPCASE(ilist)
  
  IF N_ELEMENTS(find) GT 0 THEN BEGIN
     parcheck,find,0,typ(/str),0,'FIND'
     findt = STRUPCASE(find)
  END
  
  IF N_ELEMENTS(firstt) GT 0 THEN BEGIN
     parcheck,firstt,2,TYP(/STR),0,'FIRSTTEXT'
     first = STRUPCASE(firstt)
  END
  
  IF N_ELEMENTS(lastt) GT 0 THEN BEGIN
     parcheck,lastt,3,typ(/str),0,'LASTTEXT'
     last = STRUPCASE(lastt)
  END
  
  pickfits_find

  base = WIDGET_BASE(/column,ypad=0,title='PICKFITS v11',group=group)
  
  fnt = findfont(240 - INDGEN(10)*10)
  
  dummy = WIDGET_LABEL(base, $
                       value='Select a file from the list below, edit ' + $
                       'the search string', $
                       font=fnt)
  dummy = WIDGET_LABEL(base, $
                       value='or use the Print or Quit button at the ' + $
                       'bottom', $
                       font = fnt)
  
  
  ;;; FIELD Selection section
  
  outer = WIDGET_BASE(base,/column,frame = 1,space=0)
  
  raw = WIDGET_BASE(outer,frame=0,space=0,xoffset=0,xpad=0,yoffset=0,ypad=0)
  dummy = WIDGET_LABEL(raw,value='FIELDS to include in list display:')
  
  ;; The selection fields
  
  selection = WIDGET_BASE(outer,/row,xpad=0,ypad=0,space=0)
  
  subbases = 10
  fieldno = 0
  
  nlines = ((N_ELEMENTS(allfields)+subbases-1)/subbases)
  fieldbutton = lonarr(N_ELEMENTS(allfields))
  
  ;; Place the field buttons in <subbases> columns
  
  FOR subb = 0,subbases-1 DO BEGIN
     subbase = WIDGET_BASE(selection,/column,/nonexclusive,xpad=0,ypad=0)
     FOR i = 0,nlines-1 DO BEGIN
        IF fieldno GT N_ELEMENTS(allfields)-1 THEN GOTO,SELECTION_FINISHED
        IF STRPOS(pickf_fields,allfields(fieldno)) GT -1 THEN BEGIN
           status = 1
           uvalue = '++-'
           IF fieldno EQ 0 THEN uvalue = '+++' ; Filename cannot be turned off
        END ELSE BEGIN
           status = 0
           uvalue = '+-+'
        END
        fieldbutton(fieldno) =  $
           WIDGET_BUTTON(subbase,value=allfields(fieldno),uvalue=uvalue)
        WIDGET_CONTROL,fieldbutton(fieldno),set_button=status
        fieldno = fieldno+1
     END
  END
  
  SELECTION_FINISHED:  
  
  
  ;; List
  ;; List header (top)
  raw = WIDGET_BASE(base,frame=0,space=0,xoffset=0,xpad=0,yoffset=0,ypad=0)
  head1 = WIDGET_label(raw,value=headtext,font='fixed',xoffset=3)
  
  ;; List
  list_wid = WIDGET_list(base,value=list,ysize=18,font='fixed', $
                         UVALUE='SELECT')
  WIDGET_CONTROL,list_wid,set_list_top = ((N_ELEMENTS(list)-18) > 0)
  
  ;; List header (bottom)
  raw = WIDGET_BASE(base,frame=0,space=0,xoffset=0,xpad=0,yoffset=0,ypad=0)
  head2 = WIDGET_label(raw,value=headtext,font='fixed',xoffset=3)
  
  ;; Store widget id's 
  WIDGET_CONTROL,selection,set_uvalue = {head1:head1,head2:head2, $
                                         fieldbutton:fieldbutton,$
                                         control:control, $
                                         allfields:allfields}
  
  
  ;; FIRST/LAST labels/texts
  ;;
  raw = WIDGET_BASE(base,/row,frame=0,space=0,xoffset=0,xpad=0, $
                    yoffset=0,ypad=0)
  dummy = WIDGET_LABEL(raw,value='Search between (e.g., "1996/04"):', $
                       font='fixed')
  dummy = WIDGET_TEXT(raw,value=first,uvalue='FIRST',/EDITABLE,font='fixed')
  
  dummy = WIDGET_LABEL(raw,value=' and (e.g., "1996/05")',font='fixed')
  dummy = WIDGET_TEXT(raw,value=last,uvalue='LAST',/EDITABLE,font='fixed')
  
  ;; FIND label/text
  ;;
  raw = WIDGET_BASE(base,/row,frame=0,space=0,xoffset=0,xpad=0, $
                    yoffset=0,ypad=0)
  default,find,''
  dummy = WIDGET_LABEL(raw,value='Search string:',font='fixed')
  find_wid = WIDGET_TEXT(raw,value=findt,uvalue='FILTER',/EDITABLE, $
                         font='fixed',xsize=80)
  raw = WIDGET_BASE(base,/row)
  dummy = WIDGET_LABEL(raw,value= $
                       "Operators : " + $
                       "&=AND,   |=OR,   $=AND(low precedence)",font='fixed')
  
  ;; PRINT/QUIT buttons
  ;;
  raw = WIDGET_BASE(base,/row,frame=0,space=0,xoffset=0,xpad=0, $
                    yoffset=0,ypad=0)
  xpdmenu,['"Print" {','"To file" PRINTF','"To printer" PRINTP'],raw, $
     font = fnt
  quit = WIDGET_BUTTON(raw,value='Quit',UVALUE='QUIT',font=fnt)
  
  ;; Button for spawning dsp_menu
  IF NOT KEYWORD_SET(sumer) THEN BEGIN
     dummy = WIDGET_LABEL(raw,value='                              ')
     raw2 = WIDGET_BASE(raw,/nonexclusive)
     dummy = WIDGET_BUTTON(raw2,value='Send file to DSP_MENU',uvalue='SPAWN', $
                           font = fnt)
     WIDGET_CONTROL,dummy,set_button=menu
  END
  
  storage = handle_create()
  WIDGET_CONTROL,base,set_uvalue=storage
  
  WIDGET_CONTROL,base,/realize
  WIDGET_CONTROL,find_wid,/input_focus
  WIDGET_CONTROL,find_wid,set_text_select=STRLEN(find)
  
  IF NOT KEYWORD_SET(modal) THEN BEGIN
     XMANAGER,'PICKFITS',base
  END ELSE BEGIN
     ;; Use a modal xmanager loop (to avoid xmanager fallthroughs)
     
     XMANAGER,'PICKFITS',BASE,/modal
     
     ;; Retrieve the index of the selected file
     handle_value,storage,index
     handle_free,storage
     
     
     IF N_ELEMENTS(index) EQ 1 THEN BEGIN
        IF KEYWORD_SET(sumer) THEN BEGIN
           line = list[index]
           name = (str_sep(line,' '))[0] 
           fil = find_with_def(name,"$SUM_FITS_DATA",".fits")
           IF fil EQ '' THEN MESSAGE,"Cannot find that fits file" 
           rd_sumer,fil,qlds,sumdata
        END ELSE BEGIN
           pickfits_fitsread,index,qlds
        END
     END 
  END
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; End of 'pickfits.pro'.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



