Autolisp list_box operation

Autolisp list_box operation

CSM_MAI
Advocate Advocate
4,025 Views
12 Replies
Message 1 of 13

Autolisp list_box operation

CSM_MAI
Advocate
Advocate

I have a dialog box with two list boxes. The list on the top is populated by a user browsing to a directory, and then the .dwg's are populated into that list_box "list1". That part works. I've seen a few examples of this same type of operation, but I have no idea how it works. I want the capability to select a number of files from "list1" and after they are selected, click a button to add them to the second list_box "list2". I have the multiple selection part right, but I can't seem to create a new list based on the selections in the old list. Some information on how to achieve these functions would be great. I've found plenty of examples, but like I said before, I'm not well versed enough to be able to decipher what it's doing. Thanks. 

 

I have (setq dfiles for the list of drawings in list1. If I could append that based on my selection? 

0 Likes
Accepted solutions (1)
4,026 Views
12 Replies
Replies (12)
Message 2 of 13

ambrosl
Autodesk
Autodesk

Could you post the DCL and LSP files that you have created so far?  It might help others be able to answer your question with more accuracy.



Lee Ambrosius
Senior Principal Content Experience Designer
For additional help, check out the AutoCAD Developer Documentation
0 Likes
Message 3 of 13

CSM_MAI
Advocate
Advocate

I sent you a message, but I cleaned up the lisp instead. Basically I can navigate to the directory, fill up list_box "subdirs" and select multiple entities. I need to build a list off of my selection of the files in "subdirs" and then populate "dwgs" with the selected items. That's where I run into this roadblock, among others, but i'm taking this one problem at a time. It may still be jumbled up, but here is the .lsp and dcl. Any information would be helpful. 

 

;;; DCL key information
;;;
;;; key = udir (edit box)
;;; key = browse (browse button)
;;; key = subdirs (list box left)
;;; key = dwgs (list box right)
;;; key = afiles (add files button)
;;; key = rfiles (remove files button)
;;; key = script (popup list)
;;; key = run (run button)
;;; key = cancel (cancel button)
;;;
;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
;;; ;;;
;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
(defun c:batchtest ()
(vl-load-com)

;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
(setq dcl_id (load_dialog "batchtest.dcl")) ; Load the DCL File
(if (not (new_dialog "batchtest" dcl_id)) ; Load the dialogue box
(exit) ; If not loaded exit
);end if

;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
(setq dfiles nil)
(setq sname '("script1" "script2" "script3" "script4" "script5"))
; end setq sname - list of script files the User can choose from
;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

(setq userfilepath nil)
(setq userfilepath (getvar "dwgprefix"))
;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

(set_tile "udir" userfilepath)
(mode_tile "udir" 1)
(setq dfiles nil)
(setq dfiles (vl-sort (vl-directory-files userfilepath "*.dwg")'<))
(start_list "subdirs")
(mapcar 'add_list dfiles)
(end_list)


;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

 


;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

(defun getdwgs ()
(setq userfilepath (dwgdirr "Select Folder Location:" "" 512))
(set_tile "udir" userfilepath)
(setq dfiles (vl-sort (vl-directory-files userfilepath "*.dwg")'<))
(start_list "subdirs")
(mapcar 'add_list dfiles)
(end_list)
)
;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

;(defun addfiles ()
;;;;
😉

 


;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
(start_list "script")
(mapcar 'add_list sname)
(end_list)
;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+


;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

(action_tile "accept"
(strcat
"(progn
(setq scr (get_tile \"script\"))"
"(done_dialog)(setq userclick T))"
);strcat
); action_tile
(action_tile "browse" "(setq userfilepath (getdwgs))")
(princ userselection)



;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
(start_dialog)
(unload_dialog dcl_id)
(if userclick
(progn
(setq scr (fix scr))
(setq scr (nth scr sname))

);progn
); end if userclick

 

(princ)
); defun
(princ)

;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
;;; ;;; from Lee mac
;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
(defun dwgdirr ( msg dir bit / err fld pth shl slf )
(setq err
(vl-catch-all-apply
(function
(lambda ( / app hwd )
(if (setq app (vlax-get-acad-object)
shl (vla-getinterfaceobject app "shell.application")
hwd (vl-catch-all-apply 'vla-get-hwnd (list app))
fld (vlax-invoke-method shl 'browseforfolder (if (vl-catch-all-error-p hwd) 0 hwd) msg bit dir)
)
(setq slf (vlax-get-property fld 'self)
pth (vlax-get-property slf 'path)
pth (vl-string-right-trim "\\" (vl-string-translate "/" "\\" pth))
)
)
)
)
)
)
(if slf (vlax-release-object slf))
(if fld (vlax-release-object fld))

(if shl (vlax-release-object shl))

(if (vl-catch-all-error-p err)
(prompt (vl-catch-all-error-message err))
pth
)
;(princ pth)
)

 

 

;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

;;; -------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

 

// BatchProcess multiple drawing

batchtest : dialog { // Drawing files
label = "Batch Processing";
: boxed_column {
label = "Drawings to Process:";

:row {

: text {
width = 32;
label = "Folder:";
} // text

} // row

: row {

: edit_box {
width = 50;
fixed_height = true;
key = "udir";
} // edit_box

: button {
label = "Browse";
key = "browse";
width = 12;
mnemonic = "0";
is_default = false;
mnemonic = "B";
} // button

: spacer { width = 1; }

} //row

: spacer { width = 1; }

: row {

: list_box {
key = "subdirs";
width = 40;
height = 10;
multiple_select = true;
value = "";
} // list_box

} // row

: spacer { width = 1; }

: row {

: button {
label = "Add Files";
key = "afiles";
width = 5;
fixed_width = false;
is_default = true;
mnemonic = "A";

alignment = centered;
} // button

} // row

: spacer { width = 1; }

: row {

: list_box {
key = "dwgs";
width = 40;
height = 10;
multiple_select = true;
value = "";
} // list_box

} // row

: spacer { width = 1; }

: row {

: button {
label = "Remove Files";
key = "rfiles";
width = 5;
fixed_width = false;
is_default = false;
mnemonic = "F";
alignment = centered;
} // button

} // row

} // column

: row {
: text {
width = 32;
label = "Script Type:";
} // text
} // row

: row {
: popup_list {
key = "script";
width = 40;
fixed_width = true;
value = "1" ;
} // popup_list

: button {
label = "Run";
key = "run";
width = 12;
fixed_width = true;
mnemonic = "0";
is_default = true;
mnemonic = "R";
} // button

: button {
label = "Cancel";
key = "Cancel";
width = 12;
fixed_width = false;
mnemonic = "C";
is_cancel = true;
} // button

} //row

: spacer { width = 2; }

: row {

: text {
width = 32;
label = "text";
} // text

} //row

} // batchtest

0 Likes
Message 4 of 13

scot-65
Advisor
Advisor
From the code below, there is no action_tile for the add and remove buttons?
afiles, rfiles.
Make a call to a subroutine and build/append/remove/sort/check for
duplicates the (second) list for the second list box.
When done, start_list... to show.
Do you want to remove the file names from the first list box?
Again, append/remove/sort the (first) list as needed.

???

Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

0 Likes
Message 5 of 13

CSM_MAI
Advocate
Advocate
The idea is to keep the list in "subdirs" the same and select items from that list and populate list_box "dwgs" with that selection. I haven't gotten to the add and remove buttons yet simply because I'm not sure how to create a new list from "dfiles" selection and apply it to a button. That was my next hurdle. How do you create a list from the selections of an existing list?
0 Likes
Message 6 of 13

Ajilal.Vijayan
Advisor
Advisor

@CSM_MAI wrote:
How do you create a list from the selections of an existing list?

You have to read the value of the list to get the selection.

 

The below function MK_LIST , I have taken from here.

This function will return the list of selected items.

 

Along with the function add the action_tile for the 'afiles' button.

 

(defun MK_LIST (readlist / count item retlist)
  (setq count 1)
  (while (setq item (read readlist))
    (setq retlist (cons (nth item dfiles) retlist))
    (while (and (/= " " (substr readlist count 1))
                       (/= "" (substr readlist count 1)))
      (setq count (1+ count))
    )
    (setq readlist (substr readlist count))
  )
  (reverse retlist)
)


(action_tile "afiles"
	(strcat
	"(setq selectionlist(MK_LIST (get_tile \"subdirs\")))"
	"(start_list \"dwgs\")"
	"(mapcar 'add_list selectionlist)"
	"(end_list)"
	)
)
Message 7 of 13

CSM_MAI
Advocate
Advocate

That worked great. I appreciate you writing that. I saw that post online while looking a few days ago, but I didn't know enough about how it works to be able to incorporate it to the lisp i'm working on. I copied the same function down to the del_list defun, but as I expected, it doesn't work the same way when removing items from the list. I can select the items I want to remove, but it removes the unslected items instead. It works backwards in a sense. I've tried a few changes to it, but it still will not work.  I've seen vl-remove in the autodesk help, but I'm not familiar with how to get it to work.  Below is what I was working with, but like I said, it works backwards. It reads the current list "selectionlist" that "MK_LIST" creates, but it removes the unselected items when I click the "remove" button. I'm sure that makes sense to someone who knows how this piece of code works, but I'm new to list manipulation in Autolisp. Any information would be helpful.

 

 

 

(defun DEL_LIST (readlist / count item retlist)
(setq count 1)
(while (setq item (read readlist))
(setq retlist (cons (nth item selectionlist) retlist))
(while (and (/= " " (substr readlist count 1))
(/= "" (substr readlist count 1)))
(setq count (1+ count))
)
(setq readlist (substr readlist count))
)
(reverse retlist)
)

 

 

 

 

 

action_tile "rfiles"
(strcat
"(setq removallist(del_list (get_tile \"dwgs\")))"
"(start_list \"dwgs\")"
"(mapcar 'add_list removallist)"
"(end_list)"

0 Likes
Message 8 of 13

Ajilal.Vijayan
Advisor
Advisor
Accepted solution

The DEL_LIST function is same as MK_LIST function which returns the items selected in the listbox.

So I have created two functions by taking the common parts of MK_LIST.

1. getSelctedIndexList function will return the selected indexes of a listbox.

This function can be used to convert the string value of listbox selected items.

Because (get_tile \"listboxname\") will return the selected items as string ( eg: "0 2 3")

 

2.AddRemoveItems function will take the sourcelist and the output of getSelctedIndexList function to return the items based on the third parameter (add?)

 

So no need to use DEL_LIST and MK_LIST function in your code, as these two functions will cover its job.

 

Also make sure that the variables in your lisp is declared as local

(defun c:batchtest ( / selectionlist dfiles etc....)

 

;;Returns the List of selected indexes of a listbox
;;  Arguments:
;;  sellist - string of selected items in a listbox (eg: "0 2 3")
(defun getSelctedIndexList(sellist / count item retlist)
(setq count 1)
  (while (setq item (read sellist))
    (setq retlist (cons item retlist))
    (while (and 
				(/= " " (substr sellist count 1))
				(/= "" (substr sellist count 1))
			)
	(setq count (1+ count))
    )
    (setq sellist (substr sellist count))
  )
  (reverse retlist)
)


;;Returns the List based on the User Selection
;;  Arguments:
;;  source - list of all the items
;;  selctn - list of selected index (use getSelctedIndexList function to get this)
;;  add?   - boolean , T to add and F to remove
(defun AddRemoveItems(source selctn add? / addlist removelist)
(mapcar '(lambda (x) (if(member(vl-position x source) selctn)
			(setq addlist(cons x addlist))
			(setq removelist(cons x removelist)) 
		))source)
	(if add? (reverse addlist) (reverse removelist))
) 

 

Then you can define the button action like this.

(action_tile "afiles"
	(strcat
	"(setq selectionlist (AddRemoveItems dfiles(getSelctedIndexList (get_tile \"subdirs\")) T))"
	"(start_list \"dwgs\")"
	"(mapcar 'add_list selectionlist)"
	"(end_list)"
	)
)

(action_tile "rfiles"
	(strcat
	"(setq selectionlist (AddRemoveItems selectionlist(getSelctedIndexList (get_tile \"dwgs\")) F))"
	"(start_list \"dwgs\")"
	"(mapcar 'add_list selectionlist)"
	"(end_list)"
	)
)  

 

Message 9 of 13

CSM_MAI
Advocate
Advocate

That worked great. I appreciate you taking the time to answer this. 

0 Likes
Message 10 of 13

adcobb
Participant
Participant

Can you attach the working updated code for the lisp routine and dialog box as a file?

It sounds like exactly what I have been looking for..

 

thanks,

0 Likes
Message 11 of 13

Sea-Haven
Mentor
Mentor

Lee-Mac.com has a nice list box select that allows selecting and adding to second list box. Trying to remember its name.

 

 

0 Likes
Message 12 of 13

adcobb
Participant
Participant
Thanks for the info.
I have attached an Excel spreadsheet with vba code from autocad University some years ago.
Previously I could change version number in vba code to work with new versions of autocad but this doesn't seem to work for 2023.
Any ideas?
Thanks,
0 Likes
Message 13 of 13

Sea-Haven
Mentor
Mentor

Is this question relevant to this post ? Maybe start a new post and make sure xls is attached.

0 Likes