; $Id: cw_filesel.pro,v 1.61 2001/04/04 20:46:13 ali Exp $ ; ; Copyright (c) 1998-2001, Research Systems, Inc. All rights reserved. ; Unauthorized reproduction prohibited. ;+ ; NAME: ; CW_FILESEL ; ; PURPOSE: ; This is a compound widget for file selection. ; ; CATEGORY: ; Input/Output ; ; CALLING SEQUENCE: ; Result = CW_FILESEL(Parent) ; ; INPUTS: ; Parent - The widget ID of the parent. ; ; OPTIONAL KEYWORDS: ; ; FILENAME ; Set this keyword to have the initial filename filled in the filename text area. ; ; FILTER - Set this keyword to an array of strings determining the ; filter types. If not set, the default is "All Files". All ; files containing the chosen filter string will be displayed ; as possible selections. "All Files" is a special filter ; which returns all files in the current directory. A single ; filter "field" may have several filters separated by a comma. ; ; Example: FILTER=['All Files', '.txt', '.jpg,.jpeg'] ; ; FIX_FILTER - If set, the user can not change the file filter. ; ; FRAME - If set, a frame is drawn around the widget. ; ; IMAGE_FILTER - If set, the filter "Image Files" will be added to the ; list of filters. If set, and FILTER is not set, ; "Image Files" will be the only filter displayed. Valid ; image files are determined from QUERY_IMAGE. ; ; MULTIPLE - If set, the file selection list will allow multiple ; filenames to be selected. The filename text area will not ; be editable in this case. MULTIPLE and SAVE are exclusive ; keywords. ; ; PATH - Set this keyword to the initial path the widget is to start ; in. The default is the current directory. ; ; SAVE - If set, the dialog will change to a file saving interface. ; The "Open" button changes to "Save" and the "Filter" dialog ; is named "Save as:". SAVE and MULTIPLE are exclusive keywords. ; ; UVALUE - The "user value" to be assigned to the widget. ; ; UNAME - The "user name" to be assigned to the widget. ; ; WARN_EXIST - If set, the user is warned if a filename is chosen ; that matches an already existing file. This is useful in ; routines that save to a file. ; ; OUTPUTS: ; This function returns its Widget ID. ; ; EXAMPLE: ; ; fileSel = CW_FILESEL(myBase) ; ; Using CW_FILESEL ; The widget has a string value that is the currently-selected filename: ; WIDGET_CONTROL, fileSel, GET_VALUE=filename ; To set the filename, use the command: ; WIDGET_CONTROL, fileSel, SET_VALUE=string ; ; MODIFICATION HISTORY: ; Written by: Scott Lasica, July, 1998 ; CT, RSI, July 2000: Minor rewrite. Change dir sorting on Windows. ; Added WARN_EXIST. ;- ; function Filename_Path_Sep, fullName, PATH=path COMPILE_OPT HIDDEN, STRICTARR filename = '' path = '' delimit = STRPOS(fullName, PATH_SEP(), /REVERSE_SEARCH) if (delimit gt -1) then begin filename = STRMID(fullName, delimit+1) path = STRMID(fullName, 0, delimit+1) endif $ else begin filename = fullName path='' endelse return, filename end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function cw_fileSel_isDir, name COMPILE_OPT hidden, STRICTARR return, STRPOS(name, PATH_SEP()) ne -1 end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FUNCTION cw_fileSel_continue, fullfilename, filename, action, id COMPILE_OPT hidden, STRICTARR dummy = FINDFILE(fullfilename, COUNT=cnt) IF (cnt LT 1) THEN RETURN, 1 result = DIALOG_MESSAGE([filename + ' already exists.', $ 'Continue with ' + action + '?'], $ DIALOG_PARENT=id, $ /DEFAULT_NO, /QUESTION, TITLE='File Exists') RETURN, (result EQ 'Yes') END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pro cw_fileSel_dirHelp, files, filter COMPILE_OPT HIDDEN, STRICTARR if (filter ne 'All Files') then begin if (filter ne 'Image Files') then begin if (STRPOS(filter, ',') ne -1) then $ mfilter = STRTOK(filter, ',', /EXTRACT) $ else $ mfilter = filter oldFiles = files files = '' for i=0,N_ELEMENTS(mfilter)-1 do begin mfilter[i] = STRTRIM(mfilter[i],2) test = WHERE(STRPOS(STRUPCASE(oldFiles),STRUPCASE(mfilter[i])) ge 0) if (test[0] ne -1) then $ files = [files, oldFiles[test]] endfor if (N_ELEMENTS(files) eq 1) then $ files = -1 $ else $ files = files[1:N_ELEMENTS(files)-1] endif $ else begin ;; This needs to query the image types for i = 0,N_ELEMENTS(files)-1 do begin CATCH, errorStatus IF (errorStatus NE 0) THEN CONTINUE if (not QUERY_IMAGE(files[i])) then $ files[i] = '' endfor CATCH, /CANCEL test = WHERE(files ne '') if (test[0] ne -1) then $ files = files[test] $ else $ files = -1 endelse endif end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This function will return a string array of all the directories and ;; files for the current dir function cw_fileSel_GetDirs, FILTER = filter COMPILE_OPT HIDDEN, STRICTARR WIDGET_CONTROL,/HOURGLASS allFiles = FINDFILE(COUNT=cnt) dFiles = -1 case !version.os_family of 'unix': begin spawn,'ls -laL', theDirs, /sh numfound = N_ELEMENTS(theDirs) if (numfound gt 0) then begin type = STRUPCASE(STRMID(theDirs,0,1)) dirs = WHERE(type eq 'D', found) if (found gt 0) then begin dirs = theDirs[dirs] spaceinds = WHERE(BYTE(dirs[0]) eq 32) spaceindx = SPACEINDS[N_ELEMENTS(SPACEINDS)-1] dirs = STRMID(dirs, spaceindx+1)+'/' valid = WHERE((dirs ne '../') and (dirs ne './')) cd,CURRENT=curDir if (valid[0] ne -1) then begin dirs = dirs[valid] endif endif if (N_ELEMENTS(dirs) gt 0) then begin dirs = dirs[sort(dirs)] endif else dirs=-1 files = WHERE(type eq '-', found) if (found gt 0) then begin files = theDirs[files] files = STRMID(files, spaceindx+1) cw_fileSel_dirHelp, files, filter dFiles = files endif $ else $ files = -1 if (size(dirs,/TYPE) eq 7) then begin if (size(dFiles,/TYPE) eq 7) then $ dFiles = [dirs,dFiles] $ else dFiles = dirs endif endif end 'Windows': begin dirs = '' files = '' whereDir = WHERE(STRPOS(allFiles,'\') ne -1, isDir, $ COMP=whereFiles, NCOMP=nFiles) IF (isDir GT 0) THEN BEGIN dirTemp = allFiles[whereDir] notDotDir = WHERE((dirTemp NE '..\') AND (dirTemp NE '.\'), nNot) IF (nNot GT 0) THEN dirs = [dirs, dirTemp[notDotDir]] ENDIF IF (nFiles GT 0) THEN files = [files, allFiles[whereFiles]] if (N_ELEMENTS(dirs) gt 1) then begin dirs = dirs[1:*] dirs = dirs[sort(STRUPCASE(dirs))] endif if (N_ELEMENTS(files) gt 1) then begin files = files[1:N_ELEMENTS(files)-1] cw_fileSel_dirHelp, files, filter dFiles = files endif $ else $ files = -1 if (dirs[0] ne '') then begin if (size(dFiles,/TYPE) eq 7) then $ dFiles = [dirs,dFiles] $ else dFiles = dirs endif end 'MacOS': begin dirs = '' files = '' whereDir = WHERE(STRPOS(allFiles,':') ne -1, isDir, $ COMP=whereFiles, NCOMP=nFiles) IF (isDir GT 0) THEN dirs = [dirs, allFiles[whereDir]] IF (nFiles GT 0) THEN files = [files, allFiles[whereFiles]] if (N_ELEMENTS(dirs) gt 1) then begin dirs = dirs[1:*] dirs = dirs[sort(dirs)] dirs = ':'+dirs endif if (N_ELEMENTS(files) gt 1) then begin cw_fileSel_dirHelp, files, filter dFiles = files endif $ else $ files = -1 if (dirs[0] ne '') then begin if (size(dFiles,/TYPE) eq 7) then $ dFiles = [dirs,dFiles] $ else dFiles = dirs endif end 'vms': begin ;; Getting different drives is not supported dirs = '' files = '' for i=0, cnt-1 do begin if (STRPOS(allFiles[i],'DIR', $ STRPOS(allFiles[i],'.', /REVERSE_SEARCH)) ne -1) $ then begin dirs = [dirs, '[.'+STRMID(allFiles[i], STRPOS(allFiles[i],']')+1,$ STRPOS(allFiles[i],'.DIR;')-(STRPOS(allFiles[i],']')+1))+']'] endif $ else begin files = [files, STRMID(allFiles[i], STRPOS(allFiles[i],']')+1)] endelse endfor if (N_ELEMENTS(dirs) gt 1) then begin dirs = dirs[1:*] dirs = dirs[sort(dirs)] endif if (N_ELEMENTS(files) gt 0) then begin cw_fileSel_dirHelp, files, filter dFiles = files endif $ else $ files = -1 if (dirs[0] ne '') then begin if (size(dFiles,/TYPE) eq 7) then $ dFiles = [dirs,dFiles] $ else dFiles = dirs endif end else: begin MESSAGE,'Unknown platform, aborting.' end endcase return, dFiles end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check if at top of directory FUNCTION cwfileSel_atTop, path CASE !version.os_family OF 'unix': atTop = (path EQ '/') 'Windows': atTop = (STRMID(path, STRLEN(path)-2) EQ ':\') 'MacOS': atTop = (N_ELEMENTS(STRTOK(path, ':', /EXTRACT)) EQ 1) 'vms': atTop = (STRMID(path, STRLEN(path)-8) EQ '[000000]') ENDCASE RETURN, atTop END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Make sure path ends in correct character FUNCTION cwfileSel_fixPath, path CASE !version.os_family of 'unix': if (strmid(path,strlen(path)-1,1) ne '/') then $ path = path+'/' 'Windows': if (strmid(path,strlen(path)-1,1) ne '\') then $ path = path+'\' 'MacOS': if (strmid(path,strlen(path)-1,1) ne ':') then $ path = path+':' ELSE: ENDCASE RETURN, path END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Event handler function cwfileSel_event, ev COMPILE_OPT HIDDEN, STRICTARR WIDGET_CONTROL,/HOURGLASS filename='' parent = ev.handler stash = WIDGET_INFO(parent, /CHILD) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY report_error = 1 catch, error_status if (error_status ne 0) then begin IF report_error THEN result=DIALOG_MESSAGE(!ERROR_STATE.msg,/ERROR) WIDGET_CONTROL, stash, SET_UVALUE=state,/NO_COPY return,0 endif new_event = 0 ; assume no event passed on case (ev.id) of state.dirPull: begin WIDGET_CONTROL, state.fnameText, $ SET_VALUE='' state.filename = '' drives = get_drive_list() if (drives[0] ne '') then begin cd, drives[ev.index] cd, CURRENT=currDir state.path = currDir if (PTR_VALID(state.mfilename)) then $ PTR_FREE, state.mfilename PTR_FREE, state.dFiles dFiles=cw_filesel_GetDirs(FILTER=(*state.filters)[state.filtIndex]) state.dFiles = PTR_NEW(dFiles) if (SIZE(dFiles,/TYPE) ne 7) then $ WIDGET_CONTROL, state.fileList, SENSITIVE=0, SET_VALUE='' $ else $ WIDGET_CONTROL, state.fileList, SET_VALUE=dFiles, SENSITIVE=1 WIDGET_CONTROL, state.upBut, SENSITIVE=0 WIDGET_CONTROL, state.pathLab, SET_VALUE=state.path endif end state.upBut: begin WIDGET_CONTROL, state.fnameText, $ SET_VALUE='' state.filename = '' cd, state.path case !version.os_family of 'unix': upDir = '..' 'Windows': upDir = '..' 'MacOS': upDir = '::' 'vms': upDir = '[-]' endcase cd, upDir cd, CURRENT=topCheck state.path = topCheck IF cwfileSel_atTop(topCheck) THEN $ WIDGET_CONTROL, state.upBut, SENSITIVE=0 PTR_FREE, state.dFiles dFiles = cw_filesel_GetDirs(FILTER=(*state.filters)[state.filtIndex]) state.dFiles = PTR_NEW(dFiles) if (SIZE(dFiles,/TYPE) ne 7) then $ WIDGET_CONTROL, state.fileList, SENSITIVE=0, SET_VALUE='' $ else $ WIDGET_CONTROL, state.fileList, SET_VALUE=dFiles, SENSITIVE=1 WIDGET_CONTROL, state.pathLab, SET_VALUE=state.path cd,state.oldPath end state.pathLab: begin WIDGET_CONTROL, state.pathLab, GET_VALUE=newPath IF (newPath[0] NE state.path) THEN BEGIN WIDGET_CONTROL, state.pathLab, SET_VALUE=state.path report_error = 0 ; turn off "can't change directory" warning cd, newPath[0] report_error = 1 ; turn on error messages cd, CURRENT=topCheck state.path = topCheck WIDGET_CONTROL, state.pathLab, SET_VALUE=state.path atTop = cwfileSel_atTop(topCheck) WIDGET_CONTROL, state.upBut, SENSITIVE=1-atTop PTR_FREE, state.dFiles dFiles = cw_filesel_GetDirs(FILTER=(*state.filters)[state.filtIndex]) state.dFiles = PTR_NEW(dFiles) if (SIZE(dFiles,/TYPE) ne 7) then $ WIDGET_CONTROL, state.fileList, SENSITIVE=0, SET_VALUE='' $ else $ WIDGET_CONTROL, state.fileList, SET_VALUE=dFiles, SENSITIVE=1 cd,state.oldPath ENDIF end state.fileList: begin isDirectory = cw_fileSel_isDir((*state.dFiles)[ev.index]) IF isDirectory THEN BEGIN WIDGET_CONTROL, state.fnameText, $ SET_VALUE='' state.filename = '' ENDIF CASE (ev.clicks) OF 1: begin ; single click if (isDirectory) then break if (not state.multiple) then begin WIDGET_CONTROL, state.fnameText, $ SET_VALUE=(*state.dFiles)[ev.index] state.filename = (*state.dFiles)[ev.index] endif else begin PTR_FREE,state.mfilename selected = WIDGET_INFO(state.fileList,/LIST_SELECT) if (selected[0] ne -1) then begin state.mfilename = PTR_NEW((*state.dFiles)[selected]) state.filename = (*state.dFiles)[ev.index] endif fileLabels = STRING('"'+*state.mfilename+'"', $ FORMAT='(32767(A,:,1x))') WIDGET_CONTROL, state.fnameText, $ SET_VALUE=fileLabels endelse filename = state.filename path=state.path theFilter = (*state.filters)[state.filtIndex] path = cwfileSel_fixPath(path) new_event = {FILESEL_EVENT, parent, ev.top, 0L, $ path+filename, 0L, theFilter} end ; single-click 2: begin ; double-click if (isDirectory) then begin cd, state.path cd, (*state.dFiles)[ev.index] cd, CURRENT=currDir state.path = currDir WIDGET_CONTROL, state.pathLab, SET_VALUE=state.path if (PTR_VALID(state.mfilename)) then $ PTR_FREE, state.mfilename PTR_FREE, state.dFiles dFiles=cw_filesel_GetDirs(FILTER=(*state.filters)[state.filtIndex]) state.dFiles = PTR_NEW(dFiles) if (SIZE(dFiles,/TYPE) ne 7) then $ WIDGET_CONTROL, state.fileList, SENSITIVE=0, SET_VALUE='' $ else $ WIDGET_CONTROL, state.fileList, SET_VALUE=dFiles, SENSITIVE=1 WIDGET_CONTROL, state.upBut, SENSITIVE=1 cd, state.oldPath endif else begin state.filename = (*state.dFiles)[ev.index] filename = state.filename path = state.path theFilter = (*state.filters)[state.filtIndex] path = cwfileSel_fixPath(path) continue = 1 IF state.warn_exist THEN BEGIN WIDGET_CONTROL, state.openBut, GET_VALUE=areWeSave continue = CW_FILESEL_CONTINUE(path+filename, $ filename, areWeSave, ev.handler) ENDIF IF continue THEN BEGIN WIDGET_CONTROL, state.pathLab, SET_VALUE=state.path new_event = {FILESEL_EVENT, parent, ev.top, 0L, $ path+filename, 1L, theFilter} ENDIF endelse end ; double-click endcase ; ev.click end state.fnameText: begin WIDGET_CONTROL, ev.id, GET_VALUE=filename state.filename = filename end state.filtPull: begin cd,state.path state.filtIndex = ev.index PTR_FREE, state.dFiles dFiles=cw_filesel_GetDirs(FILTER=(*state.filters)[state.filtIndex]) state.dFiles = PTR_NEW(dFiles) if (SIZE(dFiles,/TYPE) ne 7) then $ WIDGET_CONTROL, state.fileList, SENSITIVE=0, $ SET_VALUE='' $ else $ WIDGET_CONTROL, state.fileList, SET_VALUE=dFiles, $ SENSITIVE=1 theFilter = (*state.filters)[state.filtIndex] cd,state.oldPath new_event = {FILESEL_EVENT, parent, ev.top, 0L, '', 0L, theFilter} end state.openBut: begin cd,state.path test = FINDFILE(state.filename, COUNT=cnt) filename = state.filename path = state.path WIDGET_CONTROL, state.openBut, GET_VALUE=areWeSave if ((cnt gt 0) or (areWeSave eq 'Save')) then begin continue = 1 IF state.warn_exist THEN BEGIN continue = CW_FILESEL_CONTINUE(state.filename[0], $ filename, areWeSave, ev.handler) ENDIF IF continue THEN BEGIN theFilter = (*state.filters)[state.filtIndex] cd,state.oldPath path = cwfileSel_fixPath(path) new_event = {FILESEL_EVENT, parent, ev.top, 0L, $ path+filename, 1L, theFilter} ENDIF endif $ else begin void = DIALOG_MESSAGE('File not found: '+filename, /ERROR) filename='' endelse skipsave: cd,state.oldPath end state.cancBut: begin state.filename = '' state.path = '' PTR_FREE, state.mfilename state.mfilename = PTR_NEW() WIDGET_CONTROL, state.fnameText, SET_VALUE='' theFilter = (*state.filters)[state.filtIndex] new_event = {FILESEL_EVENT, parent, ev.top, 0L, '', 2L, theFilter} end else: begin result=DIALOG_MESSAGE('Unknown event.',/ERROR) end endcase WIDGET_CONTROL, stash, SET_UVALUE=state,/NO_COPY RETURN, new_event end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Set Value ;; pro CWFILESEL_SET_VALUE, id, value COMPILE_OPT HIDDEN, STRICTARR ;;Retrieve the state information. stash = WIDGET_INFO(id, /CHILD) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY if ((N_ELEMENTS(value) eq 1) and (SIZE(value[0],/TYPE) eq 7)) then begin filename = Filename_Path_Sep(value, PATH=path) state.filename = filename state.path = path cd, state.path cd, CURRENT=currDir state.path = currDir if (PTR_VALID(state.mfilename)) then $ PTR_FREE, state.mfilename PTR_FREE, state.dFiles dFiles = cw_fileSel_GetDirs(FILTER=(*state.filters)[state.filtIndex]) state.dFiles = PTR_NEW(dFiles) if (SIZE(files,/TYPE) ne 7) then $ WIDGET_CONTROL, state.fileList, SENSITIVE=0, SET_VALUE='' $ else $ WIDGET_CONTROL, state.fileList, SET_VALUE=dFiles, SENSITIVE=1 WIDGET_CONTROL, state.fnameText, SET_VALUE=value if (state.multiple) then begin PTR_FREE, state.mfilename fullNames = value filenames = STRARR(N_ELEMENTS(fullNames)) filenames[0] = Filename_Path_Sep(fullNames[0], PATH=path) state.path=path for i=1, N_ELEMENTS(fullNames)-1 do begin filenames[i] = Filename_Path_Sep(fullNames[i]) endfor state.mfilename = PTR_NEW(filenames) endif cd, state.oldPath endif WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Get Value ;; function CWFILESEL_GET_VALUE, id COMPILE_OPT HIDDEN, STRICTARR ;;Retrieve the state information. stash = WIDGET_INFO(id, /CHILD) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY path = state.path if (path ne '') then begin case !version.os_family of 'unix': path = path+'/' 'Windows': path = path+'\' else: endcase endif if (state.multiple) then $ ret = path+(*state.mfilename) $ else $ ret = path+state.filename WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY return, ret end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Kill - so clean up pro CWFILESEL_KILL, id COMPILE_OPT HIDDEN, STRICTARR ;;Retrieve the state information. WIDGET_CONTROL, id, GET_UVALUE=state, /NO_COPY cd,state.oldPath PTR_FREE, state.dFiles, state.filters, state.mfilename end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Realize the widget pro CWFILESEL_REALIZE, id COMPILE_OPT HIDDEN, STRICTARR stash = WIDGET_INFO(id, /CHILD) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY cd, CURRENT=topCheck IF cwfileSel_atTop(topCheck) THEN $ WIDGET_CONTROL, state.upBut, SENSITIVE=0 WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Main function function CW_FILESEL, parent, $ FILENAME = filename, $ FILTER = filters, $ FIX_FILTER = fix, $ FRAME = frame, $ IMAGE_FILTER = igFilter, $ MULTIPLE = mult, $ PATH = path, $ SAVE = save, $ UVALUE = uval, $ UNAME = uname, $ WARN_EXIST = warn_exist COMPILE_OPT strictarr defining = {FILESEL_EVENT, $ ID: 0L, $ TOP: 0L, $ HANDLER: 0L, $ VALUE: '', $ DONE: 0L, $ FILTER: '' $ } state = {dirPull: 0L, $ upBut: 0L, $ openBut: 0L, $ cancBut: 0L, $ fileList: 0L, $ pathLab: 0L, $ multiple: 0L, $ fnameText: 0L, $ filtPull: 0L, $ filtIndex: 0L, $ filters: PTR_NEW(), $ dFiles: PTR_NEW(), $ oldPath: '', $ currPath: '', $ path: '', $ filename: '', $ mfilename: PTR_NEW(), $ warn_exist: KEYWORD_SET(warn_exist) $ } on_error, 2 if (N_ELEMENTS(filename) gt 0) then $ state.filename = Filename_Path_Sep(filename, PATH=tPath) if (not WIDGET_INFO(parent, /VALID_ID)) then $ MESSAGE, 'Invalid widget identifier.' if (KEYWORD_SET(save) and KEYWORD_SET(mult)) then $ MESSAGE, 'Exclusive keyword error: SAVE, MULTIPLE' if (not KEYWORD_SET(frame)) then frame = 0 if (not KEYWORD_SET(uval)) then uval = 0 if (not KEYWORD_SET(uname)) then uname = 'CW_FILESEL_UNAME' if (not KEYWORD_SET(fix)) then no_edit = 0 if (not KEYWORD_SET(mult)) then mult = 0 state.multiple = mult base = WIDGET_BASE(parent, /COLUMN, FRAME=frame, UVALUE=uval, UNAME=uname, $ EVENT_FUNC='CWFILESEL_EVENT', $ FUNC_GET_VALUE='CWFILESEL_GET_VALUE', $ PRO_SET_VALUE='CWFILESEL_SET_VALUE', $ NOTIFY_REALIZE='CWFILESEL_REALIZE') ;; Top row for directory changing dirRow = WIDGET_BASE(base, /ROW, KILL_NOTIFY='CWFILESEL_KILL') if (N_ELEMENTS(path) gt 0) then begin cd, CURRENT=oldPath, path state.oldPath = oldPath state.path = path endif $ else begin cd, CURRENT=path state.path = path state.oldPath = path endelse if (N_ELEMENTS(filters) ne 0) then filtMask = 1 else filtMask = 0 if (KEYWORD_SET(igFilter)) then igMask = 1 else igMask = 0 if (filtMask and igMask) then filters = [filters, 'Image Files'] if (not filtMask and igMask) then filters = 'Image Files' if (not filtMask and not igMask) then filters = 'All Files' PTR_FREE, state.dFiles, state.filters dFiles = cw_fileSel_GetDirs(FILTER=filters[0]) if (SIZE(dFiles,/TYPE) ne 7) then dFiles='' state.dFiles = PTR_NEW(dFiles) state.filters = PTR_NEW(filters) bitmap_filename = FILEPATH('up1lvl.bmp', ROOT_DIR = IDL_DIR,$ SUBDIRECTORY = ['resource','bitmaps']) case !VERSION.OS_FAMILY of 'Windows': begin driveVol = 'Drive:' drives = get_drive_list() drive_loc = (WHERE(STRUPCASE(STRMID(path,0,STRPOS(path,'\')+1)) eq STRUPCASE(drives)) > 0)[0] end 'MacOS': begin driveVol = 'Volume:' drives = get_drive_list() drive_loc = (WHERE(STRMID(path,0,STRPOS(path,':')+1) eq drives) > 0)[0] end else: begin driveVol = '' end endcase if (driveVol ne '') then begin label = WIDGET_LABEL(dirRow, VALUE=driveVol) state.dirPull = WIDGET_DROPLIST(dirRow, VALUE=drives, $ UVALUE='dirPull', $ XSIZE=100, $ UNAME='CW_FILESEL_DIR_DROPLIST') WIDGET_CONTROL, state.dirPull, SET_DROPLIST_SELECT=drive_loc endif pathLabBase = WIDGET_BASE(base, /ROW) state.upBut = WIDGET_BUTTON(pathLabBase, VALUE=bitmap_filename, $ UVALUE='upBut', UNAME='CW_FILESEL_DIR_BUTTON',/BITMAP,/DYNAMIC_RESIZE) ;; Path listing state.pathLab = WIDGET_TEXT(pathLabBase, VALUE=path, XSIZE=28, YSIZE=1, $ EDITABLE=(driveVol EQ '')) ;; File list for current dir state.fileList = WIDGET_LIST(base, VALUE=dFiles, UVALUE='fileList',$ MULTIPLE=mult, UNAME='CW_FILESEL_FILELIST') WIDGET_CONTROL, state.fileList, YSIZE=8 ; set after because of VMS bug ;; Filename, filter, buttons fileBase = WIDGET_BASE(base, COLUMN=2) state.fnameText = CW_FIELD(fileBase, TITLE='File name:', UVALUE='fnameText',$ /ALL_EVENTS, NOEDIT=(mult), VALUE=state.filename, $ UNAME='CW_FILESEL_FILENAME') if (KEYWORD_SET(save)) then begin butVal = 'Save' filtTitle = 'Save as:' endif $ else begin butVal = 'Open' filtTitle = 'Filter:' endelse if (KEYWORD_SET(fix)) then $ filters = filters[0] state.filtPull = WIDGET_DROPLIST(fileBase, VALUE=filters, UVALUE='filtPull',$ TITLE=filtTitle, UNAME='CW_FILESEL_FILTER') state.openBut = WIDGET_BUTTON(fileBase, VALUE=butVal, UVALUE='openBut', UNAME='CW_FILESEL_OPEN') state.cancBut = WIDGET_BUTTON(fileBase, VALUE='Cancel', UVALUE='cancBut', UNAME='CW_FILESEL_CANCEL') WIDGET_CONTROL, CANCEL_BUTTON=state.cancBut, $ DEFAULT_BUTTON=state.openBut cd, state.oldPath WIDGET_CONTROL, WIDGET_INFO(base,/CHILD), SET_UVALUE = state, /NO_COPY return, base end