Fanning Software Consulting

Remembering the Last Directory

QUESTION: I have written an image display program in IDL. If I don't pass the program the name of the image file to read, the program asks me to choose an image file by using Dialog_Pickfile. This is extremely convenient, but the image files can be in a lot of different places on my computer, including on network disks. Dialog_Pickfile always starts up in IDL's current working directory. I know I can set the switch that allows IDL to change it's current working directory to the directory specified in the OpenR command, but I don't want to change the current working directory. I just want Dialog_Pickfile to remember the last location in which I opened a file. Is this possible?

ANSWER: Yes, it is possible. I have similar programs, all of which use Dialog_Pickfile to select the names of image files. But I am even more fussy. I want each program to remember which directory it last used to open a file. And I want this to occur in the entire IDL session, not just when the program is actually running. In other words, no matter how many times I run and quit the program, I want it to remember the last directory it used to open a file. Different programs will have different last directories.

This clearly calls for some kind of globally accessible variable. You could use, for example, a common block to store the last directory, or you could define and use an environment variable (see SetEnv and GetEnv). But I tend to use a hash table that is built into the Catalyst Library. I like this solution because the directory is then available from any program that wants access to it without having to do anything special in the program. The hash table is implemented with the Catalyst Library routines CatSetDefault, CatGetDefault, CatCheckDefault, and CatHelpDefaults. The Coyote and Catalyst Libraries must be installed and on your IDL Path to use this method.

I have a program, for example, named ViewFusionImage, that I use to open and display images I have created in a particular way for a particular study. The program is defined with a single positional parameter, filename, which is the name of the image file I wish to open and display. The code I use to make sure Dialog_Pickfile remembers the last directory I have used looks like this. The hash label is ViewFusionImageLastDirectory.

   ; If no filename is provided, ask the user for one. Look in the last directory
   ; you opened for the file.    IF N_Elements(filename) EQ 0 THEN BEGIN 
      ; Is the last directory already defined? If so, use it as the data directory.
      lastDir = CatGetDefault('ViewFusionImageLastDirectory', SUCCESS=success)
      IF success THEN BEGIN             
            ; The directory has been previously defined, so use it.
            DATADIR = lastDir         ENDIF ELSE BEGIN 
          ; The directory has not been previously defined, so use a generic 
          ; starting location, depending on the operating system.
          IF StrUpCase(!Version.OS_Family) EQ 'UNIX' THEN BEGIN
                DATADIR = '/homes/fanning/idl/fusion/'
          ENDIF ELSE BEGIN                 DATADIR = 'C:\IDL\fusion\'
          ENDELSE       ENDELSE 
      ; Make sure the data directory actually exists. If not, use the current directory.
      ; Save the current directory, and switch to the data directory to look for image files.
      ; Save the selected directory.
      CD, DATADIR, CURRENT=currentDir
      filename = Dialog_Pickfile(FILTER='*.img', GET_PATH=selectedDir)
      CD, currentDir 
      ; If the user cancelled from the selection, just RETURN.
      IF filename EQ "" THEN RETURN 
      ; If you have not already defined the last directory, do it now. If you have
      ; defined it, check to see if the selected directory is different from the 
      ; currently stored last directory. If it is, update it.
      IF success EQ 0 $
            THEN CatSetDefault, 'ViewFusionImageLastDirectory', selectedDir $
            ELSE IF selectedDir NE lastDir THEN CatSetDefault, 'ViewFusionImageLastDirectory', selectedDir

At any time in the IDL session, I can look to see how my current "catdefaults" are defined by using the CatHelpDefaults command.

    IDL> CatHelpDefaults
      ViewFusionImageLastDirectory    STRING    = 'C:\IDL\fusion\data\'
      Background_Color    STRING    = 'ivory'
      Axes_Color    STRING    = 'navy'
      Data_Color    STRING    = 'indian red'
      MODO2_Image_LastDirectory    STRING    = 'G:\data\modis\mod02'
      MOD09_Image_LastDirectory    STRING    = 'G:\data\modis\mod09' 

Version of IDL used to prepare this article: IDL 7.0.3.

Web Coyote's Guide to IDL Programming