Jump to content

Using vl-directory-files to populate list box


lfe011969

Recommended Posts

I'm trying to learn the vl path to lisp programming and I've run into a little snag using the 'vl-directory-files' command to populate a list box. The sample program I'm working on works fine and the contents of the folder specified in my lisp file is indeed displayed in the list box however there are two additional entries in the list, "." and ".." which I'm assuming has something to do with using vl (see pic below).

 

notes.JPG

 

Here's the code from my lisp:

(defun c:notes ()
 (setq folderList (vl-directory-files "L:\\Scripts\\Notes\\" nil -1))
 (setq dcl_id (load_dialog "notes1.dcl"))
 (if (not (new_dialog "NOTES1" dcl_id))(exit))
 (start_list "folderlist" 3)
 (mapcar 'add_list folderList)
 (end_list)
 (action_tile "cancel" "(setq ddiag 1)(done_dialog)")
 (action_tile "accept" "(setq ddiag 2)(done_dialog)")
 (start_dialog)
 (if (= ddiag 1)
   (princ "\n \n ...Notes Cancelled. \n ")
   )
 (if (= ddiag 2)
   (foreach a retList
     (princ "\n")(princ a)
     )
   )
 (princ)
 )

 

 

Does anyone know of a way to remove the "." and the ".." so they don't show in the list? The only options for vl-directory-files that I know of are 1 (show files only), 0 (show both folders and files) and -1 (show folders only).

 

Lonnie

Link to comment
Share on other sites

The "." is the current directory, and the ".." is one directory up, or the parent directory.

Just remove them from the list if not needed.

 

(vl-remove-if
 '(lambda (x) (or (eq x ".") (eq x "..")))
 (vl-directory-files "C:\\temp" nil -1)
)

Link to comment
Share on other sites

Thanks that worked great! I was actually playing around with the vl-remove command just now but couldn't get it to work. And I glanced over the directions for vl-remove-if and vl-remove-if-not but not being experienced with any of these commands I thought I'd give the base command a try first.

 

Lonnie

Link to comment
Share on other sites

Hi Lonnie,

 

Perhaps this will help you also - note how I have structured the function, and the lack of action_tile statements, using the start_dialog return.

 

(defun c:notes ( / folders dcl_id sel flag )

 (cond ( (not (setq folders (vl-remove "." (vl-remove ".." (vl-directory-files "L:\\Scripts\\Notes\\" nil -1))))))

       ( (<= (setq dcl_id (load_dialog "notes1.dcl")) 0)

         (princ "\n** Unable to Locate DCL **")
       )
       ( (not (new_dialog "NOTES1" dcl_id))

         (princ "\n** Unable to Load Dialog **")
       )
       (t
         (start_list "folderlist")
         (mapcar 'add_list folders)
         (end_list)

         (setq sel (set_tile "folderlist" "0"))
        
         (action_tile "folderlist" "(setq sel $value)")

         (setq flag (start_dialog) dcl_id (unload_dialog dcl_id))

         (if (= 1 flag)
           (princ (strcat "\nUser Selected: " (nth (atoi sel) folders)))
           (princ "\nCancelled")
         )
       )
 )

 (princ)
)

Any questions, just ask. (untested code btw).

Link to comment
Share on other sites

What does the $value represent? I won't be home for a while so I can't look this up myself (using my droid for this) and my curiosity is getting the best of me.

Link to comment
Share on other sites

It is the current value of the tile, eg. string from an edit box, or "1" or "0" from a toggle etc etc

 

See here:

 

Working with  Programmable Dialog Boxes > Managing Dialog  Boxes > Action  Expressions and Callbacks > Action Expressions

 

In ACAD Dev Help

Link to comment
Share on other sites

So I've been studying the code and I think I get what you're doing but coding-wise, I'm still crawling while you're trying to make me run a marathon, lol.

 

My intention was to start with a one-list list box routine then go to a two-list list box routine followed by a 3-list list box program. I've got some code for the 2-list program but the contents of the 2nd list box do not change based on what's selected in the first list box which is what I'm looking to do.

(defun saveVars    ()
 (setq fStr (get_tile "folderlist"))
 (if (/= fStr "")
   (progn
     (setq fIndex (atoi fStr))
     (setq fName (nth fIndex folderList))
     )
   
   (progn
     (setq fIndex -1)
     (setq fName nil)
   )
 )

 (setq nStr (get_tile "noteslist"))
 (if (/= nStr "")
   (progn
     (setq nIndex (atoi nStr))
     (setq nName (nth nIndex notesList))
     )
   (progn
     (setq nIndex -1)
     (setq nName nil)
     )
   )
 )

(defun c:notes ()
 (setq    folderList
    (vl-remove-if
      '(lambda (x) (or (eq x ".") (eq x "..")))
      (vl-directory-files "L:\\Scripts\\Notes\\" nil -1)
    )
 )

 (cond
   (= fName "Electrical")(setq folderpath "L:\\Scripts\\Notes\\Electrical\\")
   (= fName "General")(setq folderpath "L:\\Scripts\\Notes\\General\\")
   (= fName "Outfitting")(setq folderpath "L:\\Scripts\\Notes\\Outfitting\\")
   (= fName "Piping")(setq folderpath "L:\\Scripts\\Notes\\Piping\\")
   (= fName "Removal")(setq folderpath "L:\\Scripts\\Notes\\Removal\\")
   (= fName "Structure")(setq folderpath "L:\\Scripts\\Notes\\Structure\\")
   (= fName "Test")(setq folderpath "L:\\Scripts\\Notes\\Test\\")
   )

 (setq notesList
    (vl-directory-files folderpath nil 1)
   )

 (setq dcl_id (load_dialog "notes1.dcl"))
 (if (not (new_dialog "NOTES1" dcl_id))
   (exit)
 )

 (start_list "folderlist" 3)
 (mapcar 'add_list folderList)
 (end_list)

 (start_list "notelist" 3)
 (mapcar 'add_list noteList)
 (end_list)

 (action_tile "cancel" "(setq ddiag 1)(done_dialog)")
 (action_tile "accept" "(setq ddiag 2)(saveVars)(done_dialog)")
 (action_tile "folderlist" "(saveVars)")
 
 (start_dialog)
 (if (= ddiag 1)
   (princ "\n \n ...Notes Cancelled. \n ")
 )
 (if (= ddiag 2)
   (foreach a retList
     (princ "\n")
     (princ a)
   )
 )
 (princ)
)

 

 

I took the principles of a one list list box and tried to apply them to a two list one but the second list box never gets populated and the error "; error: bad argument type: stringp nil" is returned by AutoCAD as soon as any of the items in the first list box is selected.

 

How do you go about linking the two lists together so that selecting something in the 1st list changes the list in the 2nd one? Thanks.

 

Lonnie

Link to comment
Share on other sites

Just a guess it may be a problem of saying display 2nd list box but its got nothing to display so just put a blank entry into it "Pick box 1 first " when you first open the dcl then have a if pick box 1 change box2 and so on for box 3 4

Link to comment
Share on other sites

Yeah I did look over your code from that page but I'm afraid it's all greek to me, lol :bloodshot: That's why I was trying to start from scratch by building a one list box routine then progressively making my way towards a 3 list box program. I got frustrated trying to get the two list box routine to work so I started working on some other ideas I have. I'm hoping taking a day or two off from that code will give me a refreshed look when I get back to it.

 

Lonnie

Link to comment
Share on other sites

The "." is the current directory, and the ".." is one directory up, or the parent directory.

Just remove them from the list if not needed.

 

(vl-remove-if
 '(lambda (x) (or (eq x ".") (eq x "..")))
 (vl-directory-files "C:\\temp" nil -1)
)

Hi

 

Also, you can write

(vl-remove-if
 '(lambda (x) (member x '("." "..")))
 (vl-directory-files "C:\\temp" nil -1)
)

 

@+

Link to comment
Share on other sites

Hi

 

Also, you can write

(vl-remove-if
 '(lambda (x) (member x '("." "..")))
 (vl-directory-files "C:\\temp" nil -1)
)

 

@+

 

Or Lee's version...

 

(vl-remove "." 
 (vl-remove ".." 
   (vl-directory-files "L:\\Scripts\\Notes\\" nil -1)
 )
)

Link to comment
Share on other sites

Lee,

 

From your code you shared in the other post you referenced, you set up your list data into one variable called 'Data' as such:

(setq Data
    '(
      ("Ferrari"      . (("F430"     . ("2005" "2006"))
                         ("F355"     . ("1994" "1995" "1996"))
                         ("348"      . ("1989" "1990" "1991"))))

      ("Porsche"      . (("911"      . ("2007" "2008" "2009"))
                         ("928"      . ("1992" "1993" "1994"))
                         ("Boxster"  . ("2006" "2007" "2008"))))
      ("Aston Martin" . (("DB6"      . ("1965" "1966" "1967"))
                         ("Vantage"  . ("1994" "1997" "2000"))
                         ("Vanquish" . ("2005" "2006" "2007"))))
     )
 )

 

 

The program I'm working on will have the data populated from text files housed on the shared drive. If I assign variables to present the different levels of data is it just as easy to change the above code to something like this:

(setq F (vl-remove "." 
 (vl-remove ".." 
   (vl-directory-files "L:\\Scripts\\Notes\\" nil -1)
 )
)
(setq notepath (strcat "L:\\Scripts\\Notes\\" F)
(setq N (vl-directory-files notepath nil 1)
(setq Data (F   . (N    .(TBD))))

 

I'm still working on the 3rd level of data so for right now would this work for 2 levels?

 

Lonnie

Link to comment
Share on other sites

Hmmm... not sure about the way that you are getting at the file data - bear in mind that 'F' will be a list, not a string...

 

There are possibly many ways to structure the data, but in my example I found that way to be the easiest at the time of writing it, as there is a definite link between the top level item and all the sub categories - (as opposed to assigning each level to a new list bound to a new variable...)

 

Lee

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...