;------------------------------------------------------------- ;+ ; NAME: ; W_FILEOPEN ; ; PURPOSE: ; creates and handles a dialog to open a file for reading ; or writing. The dialog handles most of the parameters of ; the READDATA routine and allows to edit comments before ; saving a file. The READ and SAVE version of the dialog ; look slightly different. With a "Browse..." button, the ; dialog_pickfile widget is invoked. ; ; CATEGORY: ; file handling - widget routines - modal widget ; ; CALLING SEQUENCE: ; widget = W_FILEOPEN(PARENT [,keywords]) ; ; INPUTS: ; PARENT --> widget ID of the parent widget ; ; KEYWORD PARAMETERS: ; TITLE --> window title of the dialog box ; ; UVALUE --> a user value ; ; FILENAME --> filename to start with ; ; /READ or /SAVE --> determines appearance of the widget ; One of these should be given. ; ; COMMENTS --> a string array with comments that can be edited ; from within the SAVE version of the dialog. ; ; DELIM --> delimiter for variable names (READDATA parameter) ; ; SKP1, SKP2 --> number of lines to skip (READDATA parameter) ; ; OUTPUTS: ; w_fileopen returns a widget ID ; The event handler returns an event.info field which contains ; the filename and several parameters (delim, skp1, skp2, autoskip, ; comments) ; ; SUBROUTINES: ; FUNCTION fileopen_event, event ; handles events from fileopen dialog (notably the ; "Browse..." and "Edit comments..." buttons) ; ; REQUIREMENTS: ; ; NOTES: ; Makes most sense in conjunction with READDATA. Is used ; in EXPLORE. ; ; EXAMPLE: ; (section from EXPLORE) ; dlg = w_fileopen(title='Read Data',filename=filename, $ ; delim=delim, skp1=skp1, skp2=skp2, $ ; /READ ) ; ; widget_control,dlg,/realize ; event = widget_event(dlg) ; ; if(event.value) then begin ; info = event.info ; filename = info.filename ; delim = info.delim ; skp1 = info.skp1 ; skp2 = info.skp2 ; autoskip = info.cbox > 0 ; minimum zero ; widget_control,dlg,/hourglass ; readdata,filename,data,header,comments=comments, $ ; delim=delim,skp1=skp1,skp2=skp2, $ ; autoskip=autoskip ; endif ; ; widget_control,event.top,/destroy ; ; ; MODIFICATION HISTORY: ; mgs, 01 Dec 1997: VERSION 1.20 ; - greatly improved over version 1.00, e.g. Browse ; ;- ; Copyright (C) 1997, Martin Schultz, Harvard University ; This software is provided as is without any warranty ; whatsoever. It may be freely used, copied or distributed ; for non-commercial purposes. This copyright notice must be ; kept with any copy of this software. If this software shall ; be used commercially or sold as part of a larger package, ; please contact the author to arrange payment. ; Bugs and comments should be directed to mgs@io.harvard.edu ; with subject "IDL routine w_fileopen" ;------------------------------------------------------------- FUNCTION fileopen_event, event ; handle events from fileopen dialog ; Note that these can be slightly different depending on whether OPEN or SAVE ; file was active parent=event.handler ; the event usually must be passed further up ! ; and the next higher event handler must destroy the window ; (cannot be destroyed here, because we need the info !) passevent = 0 ; Retrieve the structure from the child that contains the sub ids. stash = WIDGET_INFO(parent, /CHILD) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY ; ---------------------------------- ; button pressed ("OK", "Cancel", or "Edit comments") ; ---------------------------------- if(event.id eq state.bID) then begin comments = state.comments if (event.value gt 1) then begin ; Edit comments dlg = w_edit(title='Edit comments',text=comments) widget_control,dlg,/realize event = widget_event(dlg) if(event.value) then begin newcomments = event.info ind = where(newcomments ne '') if (ind(0) ge 0) then comments = newcomments(ind) endif widget_control,event.top,/destroy passevent = 0 state = { bID:state.bID, nameID:state.nameID, $ searchID:state.searchID,delimID:state.delimID, $ skp1ID:state.skp1ID, skp2ID:state.skp2ID, $ cboxID:state.cboxID, comments:comments } endif else begin ; OK or Cancel widget_control,state.nameID,get_value=filename widget_control,state.delimID,get_value=delim if(delim(0) eq '') then delim = ' ' if(state.skp1ID ge 0) then begin ; only in read version widget_control,state.skp1ID,get_value=skp1 if(skp1 lt 0) then skp1 = 0 widget_control,state.skp2ID,get_value=skp2 if(skp2 lt 0) then skp2 = 0 endif else begin skp1 = -1 skp2 = -1 endelse ; get status of checkbox if (state.cboxID ge 0) then begin widget_control,state.cboxID,get_value=cbox endif else $ cbox = -1 info = { filename:filename, comments:comments, $ delim:delim, skp1:skp1, skp2:skp2, cbox:cbox } value = 1-event.value ; OK=1, Cancel=0 passevent = 1 ; this terminates the dialog endelse endif ; ---------------------------------------- ; Browse button ; ---------------------------------------- if(event.id eq state.searchID) then begin ; search button pressed widget_control,state.nameID,get_value=filename filename = strcompress(filename(0),/remove_all) if (filename ne '') then $ defpath = extract_path(filename) $ else $ defpath = '.' ; use existance of state.skp1ID to identify READ version if (state.skp1ID ge 0) then must_exist = 1 pickfilename = dialog_pickfile(file=filename, $ path=defpath,group=event.top,must_exist=must_exist, $ filter="*.dat",title='Select a File') if (pickfilename ne '') then begin filename = pickfilename ; show first 20 lines of file in extra window with no controls openr,ilun,filename,/get_lun char = '' first20 = strarr(20) inline = 0 while (not eof(ilun) AND inline lt 20) do begin readf,ilun,char first20(inline) = string(inline+1,format='(i2)') + ':' + char inline = inline + 1 endwhile close,ilun free_lun,ilun dum = w_edit(title="Preview:"+extract_filename(filename), $ text=first20, $ group_leader=event.top,yoffset=12) widget_control,dum,/realize widget_control,event.top,/show ;bring dialog back to front endif widget_control,state.nameID,set_value=filename endif ; Restore the state structure WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY if(passevent) then $ return, { ID:parent, TOP:event.top, HANDLER:0L, VALUE:value , $ INFO:info } $ else return,0 END ;----------------------------------------------------------------------------- FUNCTION w_fileopen, TITLE=title, UVALUE=uval, FILENAME=filename, $ read=read, save=save, comments=comments, $ DELIM=delim, SKP1=skp1, SKP2=skp2 ; create a dialog which varies a bit according to the /READ or /WRITE keyword ; ---------------------------------------------- ; READ: filename [Browse...] ; delim ; skp1 ; skp2 ; [] autoskip ; [OK] [Cancel] ; ; ---------------------------------------------- ; SAVE: filename [Browse...] ; delim ; [] save comments ; [OK] [Cancel] [Edit comments...] ; ; ---------------------------------------------- ; NOTE: in SAVE version, comments must be passed in order to be editable ON_ERROR,2 ; return to caller ; Defaults for keywords IF NOT (KEYWORD_SET(uval)) THEN uval = 0 if (n_elements(filename) le 0) then filename = 'test.dat' if (n_elements(delim) le 0) then delim = ' ' if (n_elements(skp1) le 0) then skp1 = 1 if (n_elements(skp2) le 0) then skp2 = 0 if (not keyword_set(title)) then title = ' ' if (n_elements(comments) le 0) then comments = '' base = WIDGET_BASE(TITLE=title, UVALUE = uval, $ frame = 3, /column, $ EVENT_FUNC = "fileopen_event" ) subbase = widget_base(base, /column, /frame) subfname = widget_base(subbase, /row) namef = cw_field(subfname,title='Filename :',value=filename,xsize=60) searchf = cw_bgroup(subfname,['Browse...']) delimf = cw_field(subbase,title='Delimiter for header :',value=delim, $ xsize=1) if (keyword_set(read)) then begin skp1f = cw_field(subbase,title='Lines to skip before header :', $ value=skp1,/integer,xsize=4) skp2f = cw_field(subbase,title='Lines to skip after header :', $ value=skp2,/integer,xsize=4) checkboxname = [ 'Autoskip' ] checkboxval = 0 endif else begin skp1f = -1 skp2f = -1 if (keyword_set(save)) then begin checkboxname = [ 'Save comments' ] checkboxval = 1 endif endelse if (n_elements(checkboxname) gt 0) then begin cboxf = cw_bgroup(subbase,/nonexclusive,checkboxname) widget_control,cboxf,set_value=checkboxval endif else $ cboxf = -1 ; no checkboxes requested (neither read nor save) buttontext = ['OK','Cancel'] if (keyword_set(save)) then buttontext = [ buttontext, 'Edit comments ...' ] buttons = cw_bgroup(base,/row,buttontext) ; IT WOULD BE NICE to have OK as default button. ; Unfortunately the following line does not work !! ; widget_control,base,default_button=buttons state = { bID:buttons, nameID:namef, searchID:searchf, $ delimID:delimf, skp1ID:skp1f, skp2ID:skp2f, cboxID:cboxf, $ comments:comments } ; Save out the initial state structure into the first childs UVALUE. WIDGET_CONTROL, WIDGET_INFO(base, /CHILD), SET_UVALUE=state, /NO_COPY RETURN, base END