Jump to content
lfe011969

Using vl-directory-files to populate list box

Recommended Posts

lfe011969

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

Share this post


Link to post
Share on other sites
rkmcswain

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)
)

Share this post


Link to post
Share on other sites
lfe011969

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

Share this post


Link to post
Share on other sites
Lee Mac

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).

Share this post


Link to post
Share on other sites
lfe011969

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.

Share this post


Link to post
Share on other sites
Lee Mac

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

Share this post


Link to post
Share on other sites
lfe011969

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

Share this post


Link to post
Share on other sites
BIGAL

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

Share this post


Link to post
Share on other sites
Lee Mac

Hi Lonnie, I have an example posted here somewhere that does EXACTLY what you are looking for, I shall find it for you :)

Share this post


Link to post
Share on other sites
Lee Mac

Actually, seems like you found it here:

http://www.cadtutor.net/forum/showthread.php?47747-List-Box-How-Do-You-Highlight-The-Value/page5

Share this post


Link to post
Share on other sites
lfe011969

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

Share this post


Link to post
Share on other sites
Patrick_35
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)
)

 

@+

Share this post


Link to post
Share on other sites
rkmcswain
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)
 )
)

Share this post


Link to post
Share on other sites
Se7en

or mine

(vl-remove-if
 '(lambda (x) (wcmatch x "`.*"))
 (vl-directory-files "C:\\tmp" nil -1)
)

Share this post


Link to post
Share on other sites
lfe011969

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

Share this post


Link to post
Share on other sites
Lee Mac

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×