; $Id: dcs_widget_filesel.pro,v 1.7 2005/09/13 20:39:46 jrdcopley Exp $
; Written by J.R.D. Copley.
;************************************************************************************************
;###############################################################################
;
; LICENSE:
;  The software in this file is written by an employee of
;  National Institute of Standards and Technology
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used or if the code in this file is
;  included in another product.
;
;###############################################################################
pro dcs_widget_filesel_handler,event
;************************************************************************************************
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pstate,/no_copy
;
ptr=(*pstate).ptr
stitle=(*pstate).stitle
sfnum=(*pstate).sfnum
slist=(*pstate).slist
done=(*pstate).done
upbutt=(*pstate).upbutt
topbutt=(*pstate).topbutt
message=(*pstate).message
currentdirlist=(*pstate).currentdirlist
drvlist=(*pstate).drvlist
dirlist=(*pstate).dirlist
filelist=(*pstate).filelist
drive=(*pstate).drive
directory=(*pstate).directory
filter=(*pstate).filter
filetypelist=(*pstate).filetypelist
listfilters=(*pstate).listfilters
start_filter=(*pstate).start_filter
starttext=(*pstate).starttext
stop_filter=(*pstate).stop_filter
stoptext=(*pstate).stoptext
listdrvs=(*pstate).listdrvs
listdirs=(*pstate).listdirs
listfiles=(*pstate).listfiles
gofind=(*pstate).gofind
help=(*pstate).help
osname=(*pstate).osname
separator=(*pstate).separator
;
evid=event.id
;
drivedirectory=drive+directory
;
if (evid eq upbutt) then begin
	tokens=strsplit(drivedirectory,separator,/extract)
	ntokens=n_elements(tokens)
	if (osname eq "Windows") then ntmin=1
	if (osname eq "unix") then ntmin=0
	if (osname eq "MacOS") then ntmin=0; (Is this OK?)
	if (ntokens gt ntmin+1) then directory=strjoin(tokens[ntmin:ntokens-2],separator)$
		+separator else directory=''
	widget_control,currentdirlist,set_value=drive+directory
	drivedirectory=drive+directory
;	widget_control,/hourglass
	widget_control,starttext,get_value=start_filter
	widget_control,stoptext,get_value=stop_filter
	dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
		start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
	widget_control,dirlist,set_value=listdirs
	nlistfiles=n_elements(listfiles)
	if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
	widget_control,message,set_value=num+" files found in this directory."
	widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
endif
;
if (evid eq topbutt) then begin
	tokens=strsplit(drivedirectory,separator,/extract)
	directory=''
	widget_control,currentdirlist,set_value=drive+directory
	drivedirectory=drive+directory
;	widget_control,/hourglass
	widget_control,starttext,get_value=start_filter
	widget_control,stoptext,get_value=stop_filter
	dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
		start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
	widget_control,dirlist,set_value=listdirs
	nlistfiles=n_elements(listfiles)
	if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
	widget_control,message,set_value=num+" files found in this directory."
	widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
endif
;
if (evid eq drvlist) then begin
	if (event.clicks eq 2) then begin
		drive=listdrvs[event.index]
		directory=''
		drivedirectory=drive+directory
;		widget_control,/hourglass
		widget_control,starttext,get_value=start_filter
		widget_control,stoptext,get_value=stop_filter
		dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
			start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
		if (nfiles ne -2) then begin
			widget_control,currentdirlist,set_value=drivedirectory
			widget_control,dirlist,set_value=listdirs
			nlistfiles=n_elements(listfiles)
			if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
			widget_control,message,set_value=num+" files found in this directory."
			widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
		endif else widget_control,message,set_value="INVALID DRIVE"
	endif
endif
;
if (evid eq dirlist) then begin
	if (event.clicks eq 2) then begin
		drivedirectory=listdirs[event.index]
		tokens=strsplit(drivedirectory,separator,/extract)
		ntokens=n_elements(tokens)
		if (osname eq "Windows") then ntmin=1
		if (osname eq "unix") then ntmin=0
		if (osname eq "MacOS") then ntmin=0; (Is this OK?)
		directory=strjoin(tokens[ntmin:ntokens-1],separator)+separator
		widget_control,currentdirlist,set_value=drivedirectory
;		widget_control,/hourglass
		widget_control,starttext,get_value=start_filter
		widget_control,stoptext,get_value=stop_filter
		dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
			start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
		widget_control,dirlist,set_value=listdirs
		nlistfiles=n_elements(listfiles)
		if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
		widget_control,message,set_value=num+" files found in this directory."
		widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
	endif
endif
;
if (evid eq filetypelist) then begin
	if (event.clicks eq 2) then begin
		filter=listfilters[event.index]
;		widget_control,/hourglass
		widget_control,starttext,get_value=start_filter
		widget_control,stoptext,get_value=stop_filter
		dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
			start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
		widget_control,dirlist,set_value=listdirs
		nlistfiles=n_elements(listfiles)
		if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
		widget_control,message,set_value=num+" files found in this directory."
		widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
	endif
endif
;
if (evid eq starttext) then begin
;	widget_control,/hourglass
	widget_control,starttext,get_value=start_filter
	widget_control,stoptext,get_value=stop_filter
	dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
		start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
	widget_control,dirlist,set_value=listdirs
	nlistfiles=n_elements(listfiles)
	if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
	widget_control,message,set_value=num+" files found in this directory."
	widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
endif
;
if (evid eq stoptext) then begin
;	widget_control,/hourglass
	widget_control,starttext,get_value=start_filter
	widget_control,stoptext,get_value=stop_filter
	dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
		start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
	widget_control,dirlist,set_value=listdirs
	nlistfiles=n_elements(listfiles)
	if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
	widget_control,message,set_value=num+" files found in this directory."
	widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
endif
;
if (evid eq gofind) then begin
;	widget_control,/hourglass
	widget_control,starttext,get_value=start_filter
	widget_control,stoptext,get_value=stop_filter
	dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
		start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
	widget_control,dirlist,set_value=listdirs
	nlistfiles=n_elements(listfiles)
	if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
	widget_control,message,set_value=num+" files found in this directory."
	widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
endif
;
if (evid eq help) then begin
	instruction=[$
		"Run types are S=Sample, C=Container, V=Vanadium, A=Absorber, B=Background.",$
		"To switch among run types click on the appropriate letter.",$
		"The current run type is displayed, as well as the number of runs selected for the run type;",$
		"''TOO MANY FILES'' is printed if you try to exceed the maximum ("$
		+strcompress((*pstate).maxnum,/remove_all)+").",$
		"To select a file double-click on its name in the main window.",$
		"To select a range of files, single-click on the first member and then single-click on the last member.",$
		"You may switch drives and/or directories, and/or modify the filter.",$
		"You can further restrict the display to files with names between ''Start at:'' and ''Stop at:''.",$
		"The bottom window, initially blank, contains the list of files you have selected.",$
		"To de-select a file from this list double-click on its name in the bottom window.",$
		"To de-select all files for the current run type click ''Clear''.",$
		"When you're done, click the ''DONE'' button.  To abort, click ''ABORT''."]
	result=dialog_message(instruction,/information,title="File Selection")
endif
;
if (evid eq done) then begin
	widget_control,event.top,/destroy
	return
endif
;
(*pstate).dirlist=dirlist
(*pstate).currentdirlist=currentdirlist
(*pstate).filelist=filelist
(*pstate).drive=drive
(*pstate).directory=directory
(*pstate).filter=filter
(*pstate).start_filter=start_filter
(*pstate).stop_filter=stop_filter
(*pstate).listfiles=listfiles
(*pstate).listdirs=listdirs
(*pstate).lasttimeclicked=0
;
widget_control,event.top,set_uvalue=pstate,/no_copy
end


;************************************************************************************************
pro dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
	start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
;************************************************************************************************
;
compile_opt strictarr
;
if (filter eq "Both") then begin
	path1=drivedirectory+"*.dcs"
	path2=drivedirectory+"*.dcs.gz"
	listfiles=[findfile(path1,count=count1),findfile(path2,count=count2)]
	count=count1+count2
endif else begin
	path=drivedirectory+filter
	listfiles=findfile(path,count=count)
endelse
;
listfiles=listfiles[sort(listfiles)]; these are the files returned by the filter, sorted.
;
ldir=strlen(drivedirectory)
if (osname eq "Windows") then begin
	if (ldir eq 3 and count eq 0) then begin; see whether it's an invalid or unavailable drive
		tmp=findfile(drivedirectory+"*",count=count)
		if (count eq 0) then begin
			nfiles=-2
			return
		endif
	endif
endif
;
listfiles=strmid(listfiles,ldir); remove drive and directory from full path name
;
if (osname eq "Windows") then begin
	findsubdirs=stregex(listfiles,'\\$'); find subdirectories (last character is "\")
	file_indices=where(findsubdirs eq -1,nfiles); indices of files
	if (nfiles eq 0) then listfiles=strarr(1) else begin
		listfiles=listfiles[file_indices]; list of files
	endelse
endif
;
file_indices=where((listfiles ge start_filter[0]) $
  and (listfiles le stop_filter[0]+"zzzzzzz"),nfiles); Apply filter
if (nfiles eq 0) then listfiles=strarr(1) else $
	listfiles=listfiles[file_indices]; list of files
;
listall=findfile(drivedirectory+"*",count=count)
listall=listall[sort(listall)]; this is a list of all files and subdirectories
;
if (osname eq "Windows") then begin
; Under Windows, FINDFILE appends a "\" character to the end of the returned
; file name if the file is a directory.
	findsubdirs=stregex(listall,'\\$',/boolean) $ ; find subdirectories, but exclude
		* (1-stregex(listall,'\\\.',/boolean)); those that contain backslash-period
	dir_indices=where(findsubdirs eq 1,ndirs); indices of subdirectories
	if (ndirs eq 0) then listdirs=strarr(1) else $; no subdirectories
		listdirs=listall[dir_indices]; list of subdirectories
	listdirs=listdirs[sort(listdirs)]; sorted list of subdirectories
endif
;
if (osname eq "unix") then begin
	findsubdirs=stregex(listall,':$',/boolean) ; find subdirectories (ending with colon)
	dir_indices=where(findsubdirs eq 1,ndirs); indices of subdirectories
	if (ndirs eq 0) then listdirs=strarr(1) else begin; no subdirectories
		listdirs=listall[dir_indices]; list of subdirectories
		for k=0,ndirs-1 do listdirs[k]=strmid(listdirs[k],0,strlen(listdirs[k])-1)+"/"
		listdirs=listdirs[sort(listdirs)]; sorted list of subdirectories
	endelse
endif
;
if (osname eq "MacOS") then begin
;	x=dialog_message("Sorry, but I don''t (yet) know how to proceed with MAC OS.")
; Under Macintosh, FINDFILE function brackets the returned filename in colons
; if the file is a folder (e.g., :lib:)
	findsubdirs=stregex(listall,':$',/boolean) ; find subdirectories (ending with colon)
	dir_indices=where(findsubdirs eq 1,ndirs); indices of subdirectories
	if (ndirs eq 0) then listdirs=strarr(1) else begin; no subdirectories
		listdirs=listall[dir_indices]; list of subdirectories
		for k=0,ndirs-1 do listdirs[k]=strmid(listdirs[k],0,strlen(listdirs[k])-1)+"/"
		listdirs=listdirs[sort(listdirs)]; sorted list of subdirectories
	endelse
endif
;
end


;************************************************************************************************
pro dcs_widget_filesel_additem,event
;************************************************************************************************
;
compile_opt strictarr
;
; Get file names and number of files for this file type.
widget_control,event.top,get_uvalue=pstate,/no_copy
fname=(*(*pstate).ptr).fname
nfname=(*(*pstate).ptr).nfname
message=(*pstate).message
done=(*pstate).done
;
drive=(*pstate).drive
directory=(*pstate).directory
listfiles=(*pstate).listfiles
;
; Get corresponding widget IDs.
sfnum=(*pstate).sfnum
slist=(*pstate).slist
;
; Respond to single clicks.
if (event.clicks eq 1) then begin
	lasttimeclicked=(*pstate).lasttimeclicked
	oldindex=(*pstate).oldindex
	if (lasttimeclicked) then begin
		lasttimeclicked=0
		position1=oldindex<event.index
		position2=oldindex>event.index
		for position=position1,position2 do begin
			if (nfname[(*pstate).kfile]+1 lt (*pstate).maxnum) then begin
				m=nfname[(*pstate).kfile]+1
				ddfile=drive+directory+listfiles[position]
				fname[(*pstate).kfile,m]=ddfile; add file name to list
				nfname[(*pstate).kfile]=m
				fname[(*pstate).kfile,0:m]=fname[(*pstate).kfile,sort(fname[(*pstate).kfile,0:m])]; sort non-blank file names
				if (m gt 0) then begin; if more than one file in list, find and remove duplicates.
					for mm=0,m-1 do begin
						if (fname[(*pstate).kfile,mm] eq fname[(*pstate).kfile,mm+1]) then begin
							 fname[(*pstate).kfile,mm:(*pstate).maxnum-2]=fname[(*pstate).kfile,mm+1:(*pstate).maxnum-1]; shift portion of list
							nfname[(*pstate).kfile]=nfname[(*pstate).kfile]-1; decrement index of last file
						endif
					endfor
				endif
			endif else widget_control,message,set_value="  TOO MANY FILES! "
;
; Update file names and number of files selected.
			widget_control,sfnum,set_value=strcompress(string(nfname[(*pstate).kfile]+1),/remove_all)
			widget_control,slist,set_value=fname[(*pstate).kfile,*]
;
; Update selected file names and number of files for this file type.
			(*(*pstate).ptr).fname=fname
			(*(*pstate).ptr).nfname=nfname
		endfor
	endif else begin
		oldindex=event.index
		lasttimeclicked=1
	endelse
	(*pstate).lasttimeclicked=lasttimeclicked
	(*pstate).oldindex=oldindex
	widget_control,event.top,set_uvalue=pstate,/no_copy
	widget_control,done,/sensitive
	widget_control,event.top,default_button=done
	return
endif
;
; Respond to double-clicking on file name in list, implying that
; the file is to be added to the list.
; Get file names and number of files for this file type.
if (event.clicks eq 2) then begin
;
; Determine which list item was double-clicked.
	position=event.index
;
	if (nfname[(*pstate).kfile]+1 lt (*pstate).maxnum) then begin
		m=nfname[(*pstate).kfile]+1
		ddfile=drive+directory+listfiles[position]
		fname[(*pstate).kfile,m]=ddfile; add file name to list
		nfname[(*pstate).kfile]=m
		fname[(*pstate).kfile,0:m]=fname[(*pstate).kfile,sort(fname[(*pstate).kfile,0:m])]; sort non-blank file names
		if (m gt 0) then begin; if more than one file in list, find and remove duplicates.
			for mm=0,m-1 do begin
				if (fname[(*pstate).kfile,mm] eq fname[(*pstate).kfile,mm+1]) then begin
					 fname[(*pstate).kfile,mm:(*pstate).maxnum-2]=fname[(*pstate).kfile,mm+1:(*pstate).maxnum-1]; shift portion of list
					nfname[(*pstate).kfile]=nfname[(*pstate).kfile]-1; decrement index of last file
				endif
			endfor
		endif
	endif else widget_control,message,set_value="  TOO MANY FILES! "
;
; Update file names and number of files selected.
	widget_control,sfnum,set_value=strcompress(string(nfname[(*pstate).kfile]+1),/remove_all)
	widget_control,slist,set_value=fname[(*pstate).kfile,*]
;
; Update selected file names and number of files for this file type.
	(*(*pstate).ptr).fname=fname
	(*(*pstate).ptr).nfname=nfname
	(*pstate).lasttimeclicked=0
	widget_control,event.top,set_uvalue=pstate,/no_copy
	widget_control,done,/sensitive
	widget_control,event.top,default_button=done
endif
;
end


;************************************************************************************************
pro dcs_widget_filesel_removeitem,event
;************************************************************************************************
;
compile_opt strictarr
;
;
; Respond to double-clicking on file name in list, implying that
; the file is to be removed. Single clicks are disregarded.
if (event.clicks eq 1) then return
;
; Get file names and number of files for this file type.
widget_control,event.top,get_uvalue=pstate,/no_copy
fname=(*(*pstate).ptr).fname
nfname=(*(*pstate).ptr).nfname
done=(*pstate).done
;
; Get corresponding widget IDs.
sfnum=(*pstate).sfnum
slist=(*pstate).slist
;
; Determine which list item was double-clicked.
position=event.index
;
; If a blank line in the list was double-clicked, disregard.
if (position gt nfname[(*pstate).kfile]) then return
; Shift portion of list
fname[(*pstate).kfile,position:(*pstate).maxnum-2]=fname[(*pstate).kfile,position+1:(*pstate).maxnum-1]
fname[(*pstate).kfile,(*pstate).maxnum-1]=""; place blank string at last position
nfname[(*pstate).kfile]=nfname[(*pstate).kfile]-1; decrement index of last file
widget_control,slist,set_value=fname[(*pstate).kfile,*]
widget_control,sfnum,set_value=strcompress(string(nfname[(*pstate).kfile]+1),/remove_all)
;
; Update file names and number of files for this file type.
(*(*pstate).ptr).fname=fname
(*(*pstate).ptr).nfname=nfname
(*pstate).lasttimeclicked=0
widget_control,event.top,set_uvalue=pstate,/no_copy
if (total(nfname) eq -5) then widget_control,done,sensitive=0
end


;************************************************************************************************
pro dcs_widget_filesel_actionbuttons,event
;************************************************************************************************
;
compile_opt strictarr
;
;
; Get file names selected so far, and numbers of files.
widget_control,event.top,get_uvalue=pstate,/no_copy
;
fname=(*(*pstate).ptr).fname
nfname=(*(*pstate).ptr).nfname
type_of_file=(*(*pstate).ptr).type_of_file
done=(*pstate).done
;
; Get corresponding widget IDs plus ID of title widget.
sfnum=(*pstate).sfnum
slist=(*pstate).slist
stitle=(*pstate).stitle
;
; Get IDs of certain buttons.
cancelid=(*pstate).cancelid
clearid=(*pstate).clearid
;
; Get ID of button pressed.
index=fix(event.id)
;
; Respond to "Next" and "Back" buttons
if (index eq (*pstate).nextid) then begin
	(*pstate).kfile=(*pstate).kfile+1
	(*pstate).kfile=(*pstate).maxtyp-1<(*pstate).kfile>0
;
; Update title.
	widget_control,stitle,set_value=type_of_file[(*pstate).kfile]
;
; Update number of files and list of selected files.
	widget_control,sfnum,set_value=strcompress(string(nfname[(*pstate).kfile]+1),/remove_all)
	widget_control,slist,set_value=fname[(*pstate).kfile,*]
endif
;
if (index eq (*pstate).backid) then begin
	(*pstate).kfile=(*pstate).kfile-1
	(*pstate).kfile=(*pstate).maxtyp-1<(*pstate).kfile>0
;
; Update title.
	widget_control,stitle,set_value=type_of_file[(*pstate).kfile]
;
; Update number of files and list of selected files.;
	widget_control,sfnum,set_value=strcompress(string(nfname[(*pstate).kfile]+1),/remove_all);
	widget_control,slist,set_value=fname[(*pstate).kfile,*]
endif
;
if (index eq cancelid) then begin
	(*(*pstate).ptr).nfname=intarr((*pstate).maxtyp)-1
	(*(*pstate).ptr).fname=strarr((*pstate).maxtyp,(*pstate).maxnum)
	widget_control,event.top,set_uvalue=pstate,/no_copy
	widget_control,event.top,/destroy
	return
endif
;
if (index eq clearid) then begin
	nfname[(*pstate).kfile]=-1
	fname[(*pstate).kfile,*]=strarr((*pstate).maxnum)
	widget_control,slist,set_value=fname[(*pstate).kfile,*]
	widget_control,sfnum,set_value=strcompress(string(nfname[(*pstate).kfile]+1),/remove_all)
	(*(*pstate).ptr).fname=fname
	(*(*pstate).ptr).nfname=nfname
	if (total(nfname) eq -5) then widget_control,done,sensitive=0
endif
;
(*pstate).lasttimeclicked=0
widget_control,event.top,set_uvalue=pstate,/no_copy
end


;************************************************************************************************
function dcs_widget_filesel_individualbuttons,event
;************************************************************************************************
;
compile_opt strictarr
;
;
; Get file names selected so far, and numbers of files.
widget_control,event.top,get_uvalue=pstate,/no_copy
;
fname=(*(*pstate).ptr).fname
nfname=(*(*pstate).ptr).nfname
type_of_file=(*(*pstate).ptr).type_of_file
;
; Get corresponding widget IDs plus ID of title widget.
sfnum=(*pstate).sfnum
slist=(*pstate).slist
stitle=(*pstate).stitle
;
; Determine which button was pressed.
(*pstate).kfile=fix(event.value)
;
; Update title.
widget_control,stitle,set_value=type_of_file[(*pstate).kfile]
;
; Update number of files and list of selected files.
widget_control,sfnum,set_value=strcompress(string(nfname[(*pstate).kfile]+1),/remove_all)
widget_control,slist,set_value=fname[(*pstate).kfile,*]
;
(*pstate).lasttimeclicked=0
widget_control,event.top,set_uvalue=pstate
end


;************************************************************************************************
pro dcs_widget_filesel,group_leader=grpled,drive=drive,directory=directory,$
	filter=filter,start_filter=start_filter,stop_filter=stop_filter,$
	files_selected,nfiles_selected,type_of_file
;************************************************************************************************
;
compile_opt strictarr
;
; Default values of drive, directory and filter
;
if (!operating_system eq "Windows") then lpath=3
if (!operating_system eq	"unix") then lpath=1
if (!operating_system eq	"MacOS") then lpath=0; Is this OK?
if (keyword_set(drive)) then drive=drive $
	else drive=strmid(!dcs_data_directory,0,lpath)
if (keyword_set(directory)) then directory=directory $
	else directory=strmid(!dcs_data_directory,lpath)
if (keyword_set(filter)) then filter=filter $
	else filter="*.dcs.gz"
;
dcs_datestring,yesterday,today,tomorrow
if (keyword_set(start_filter)) then start_filter=start_filter $
	else start_filter=strcompress(" 2000",/remove_all)
if (keyword_set(stop_filter)) then stop_filter=stop_filter $
	else stop_filter=today
;
osname=!VERSION.OS_FAMILY
case osname of
	"Windows": begin; Check whether drive, directory and filter names are OK.
		test=stregex(drive,'\\$')
		if (test eq -1) then stop,"Drive name no good."
		test=stregex(directory,'\\$')
		if (strlen(directory) gt 0 and test eq -1) then stop,"Directory name no good."
		test=stregex(filter,'^\\')
		if (test ne -1) then stop,"Filter no good."
		listdrvs=get_drive_list()
		separator="\"
	end
	"unix": begin
		listdrvs=strarr(1)
		separator="/"
	end
	"MacOS": begin
		listdrvs=strarr(1)
		separator=""
	end
	else: stop,"Unsupported operating system."
endcase
;
drivedirectory=drive+directory
;
if (keyword_set(grpled)) then group_leader=grpled $
	else group_leader=""
;
fname=files_selected
nfname=nfiles_selected-1
tmp=size(files_selected)
maxnum=tmp[2]
maxtyp=tmp[1]
;
listfilters=["*.dcs","*.dcs.gz","Both"]
filter=listfilters[2]
;
;dcs_sysdep,fonts=fonts
;
kfile=0
; Set up the widget
tlb=widget_base(title='File Selector',/col,group_leader=group_leader,/modal)
	meat=widget_base(tlb,/col,/frame,/align_center)
		shead=widget_base(meat,/row,/align_center,/frame)
			sfnum=widget_label(shead,value=" 0");,FONT = fonts[1])
			sftext=widget_label(shead,value=" file(s) selected for the ");,FONT = fonts[1])
			stitle=widget_label(shead,value="Sample      ");,FONT = fonts[1])
		toprow=widget_base(meat,/row,/align_center)
			leftcol=widget_base(toprow,/col)
				currentdrvlabel=widget_label(leftcol,value="Current drive:")
				drvlist=widget_list(leftcol,xsize=6,ysize=6)
			midcol=widget_base(toprow,/col)
				currentdirlabel=widget_label(midcol,value="Current directory:")
				currentdirlist=widget_list(midcol,ysize=1,value=drive+directory)
				butts=widget_base(midcol,/col)
					upbutt=widget_button(butts,value="Go up one directory level")
					topbutt=widget_button(butts,value="Go to top directory level")
			rightcol=widget_base(toprow,/col)
				dirlabel=widget_label(rightcol,value="Sub-directories, if any:")
				dirlist=widget_list(rightcol,xsize=45,ysize=6)
		fss=widget_base(meat,/row)
			ffilter=widget_base(fss,/row)
				filetypelabel=widget_label(ffilter,value="File type:",/align_top)
				filetypelist=widget_list(ffilter,xsize=6,ysize=3)
			start=widget_base(fss,/row)
				startlabel=widget_label(start,value="Start at:",/align_top)
				starttext=widget_text(start,xsize=12,ysize=1,/editable,value=start_filter)
			stop=widget_base(fss,/row)
				stoplabel=widget_label(stop,value="Stop at:",/align_top)
				stoptext=widget_text(stop,xsize=12,ysize=1,/editable,value=stop_filter)
			gofind=widget_button(fss,value="Click to find files");,FONT = fonts[0])
		message=widget_list(meat,/align_center,value="",xsize=55,ysize=1);,FONT = fonts[1])
		meatrow=widget_base(meat,/row)
			filecol=widget_base(meatrow,/col)
				filelabel=widget_label(filecol,value="Data files, if any:")
				filelist=widget_list(filecol,xsize=25,ysize=10,$
					event_pro='dcs_widget_filesel_additem')
			scol=widget_base(meatrow,/col)
				slabel=widget_label(scol,value="Selected files:")
				slist=widget_list(scol,xsize=60,ysize=10,$
					event_pro='dcs_widget_filesel_removeitem')
		extrab=widget_base(meat,/row,/align_center)
			clear=widget_button(extrab,value="CLEAR",uname='clear',$
				event_pro='dcs_widget_filesel_actionbuttons');,font=fonts[0])
			help=widget_button(extrab,value="HELP");,font=fonts[0])
			backid=widget_button(extrab,value="Back",$
				event_pro='dcs_widget_filesel_actionbuttons');,font=fonts[0])
			remainder=cw_bgroup(extrab,['S','C','V','A','B'],COLUMN=5,$
				event_funct='dcs_widget_filesel_individualbuttons',$
				button_uvalue=['0','1','2','3','4']);,font=fonts[0])
			nextid=widget_button(extrab,value="Next",$
				event_pro='dcs_widget_filesel_actionbuttons');,font=fonts[0])
			done=widget_button(extrab,value="DONE");,font=fonts[0])
			cancel=widget_button(extrab,value="ABORT",uname='cancel',$
				event_pro='dcs_widget_filesel_actionbuttons');,font=fonts[0])
;
; Update widget.
widget_control,sfnum,set_value=strcompress(string(nfname[0]+1),/remove_all)
widget_control,slist,set_value=fname[0,*]
;
dave_position_tlb,tlb
widget_control,tlb,/realize
;
cancelid=widget_info(tlb,find_by_uname='cancel')
clearid=widget_info(tlb,find_by_uname='clear')
;
ptr=ptr_new({fname:fname,nfname:nfname,type_of_file:type_of_file})
;
listdirs=strarr(50)
listfiles=strarr(2500)
;
state={ptr:ptr,maxnum:maxnum,maxtyp:maxtyp,kfile:kfile,$
	stitle:stitle,sfnum:sfnum,slist:slist,cancelid:cancelid,clearid:clearid,$
	done:done,upbutt:upbutt,topbutt:topbutt,message:message,$
	drvlist:drvlist,dirlist:dirlist,currentdirlist:currentdirlist,$
	filelist:filelist,listdrvs:listdrvs,listdirs:listdirs,$
	listfiles:listfiles,listfilters:listfilters,$
	drive:drive,directory:directory,filter:filter,start_filter:start_filter,$
	stop_filter:stop_filter,$
	filetypelist:filetypelist,starttext:starttext,stoptext:stoptext,$
	help:help,gofind:gofind,backid:backid,nextid:nextid,$
	lasttimeclicked:0,oldindex:0,separator:separator,osname:osname}
widget_control,tlb,set_uvalue=ptr_new(state),/no_copy
;
widget_control,drvlist,set_value=listdrvs
ndrv=where(strlowcase(drive) eq listdrvs)
widget_control,drvlist,set_list_select=ndrv
;
widget_control,filetypelist,set_value=listfilters
widget_control,filetypelist,set_list_select=2
;
if (!operating_system eq "Windows") then begin
;	widget_control,/hourglass
endif
dcs_widget_filesel_getfsdlists,drivedirectory,filter,$
	start_filter,stop_filter,ndirs,listdirs,nfiles,listfiles,osname,separator
widget_control,dirlist,set_value=listdirs
nlistfiles=n_elements(listfiles)
if (listfiles[0] eq "") then num="No" else num=strcompress(nlistfiles)
widget_control,message,set_value=num+" files found in this directory."
widget_control,filelist,set_value=listfiles,set_list_top=nlistfiles-8
;
if (total(nfname) eq -5) then widget_control,done,sensitive=0
;
widget_control,tlb,get_uvalue=pstate,/no_copy
(*pstate).listdrvs=listdrvs
(*pstate).listdirs=listdirs
(*pstate).listfiles=listfiles
widget_control,tlb,set_uvalue=pstate,/no_copy
;
; Manage the widget.
xmanager,'dcs_widget_filesel',tlb,event_handler='dcs_widget_filesel_handler',$
	/no_block,group_leader=group_leader
;
files_selected=(*ptr).fname
nfiles_selected=(*ptr).nfname+1
type_of_file=(*ptr).type_of_file
ptr_free,ptr
;
end

