How to select multiple text in a dialog box to parse through lisp routine

How to select multiple text in a dialog box to parse through lisp routine

dalennea
Enthusiast Enthusiast
5,070 Views
43 Replies
Message 1 of 44

How to select multiple text in a dialog box to parse through lisp routine

dalennea
Enthusiast
Enthusiast

I hope that someone is able to steer me in the right direction. I have created a dialog box that reads in a list of the layers that did not process through a program that I wrote.  Now I built the DCL and have the list of the layers showing up in that dialog box (i.e. list box in DCL) and want to be able to select those layer names either individually or a set and then have them run a routine that will convert the selected layers to the layer that is identified by means of the "radial button".  I have included a pic to hopefully make it clear as to what I want to accomplish... I need some help in how to accomplish this in lisp... 

 

 

Thanks in advance

0 Likes
5,071 Views
43 Replies
Replies (43)
Message 2 of 44

scot-65
Advisor
Advisor

Dale,

I am a little rusty, but I'll try...

 

I would convert the radial buttons to just buttons (one less mouse click).

Include a few of those already showing on the bottom.

I would also include a "Remove From List" button (Ignore me).

In the DCL, set multi-select to true for the list_box (default is false).

In the action_tile, make a call to (setq b (get_tile "Listbox1")).

What will be returned is a string of the highlighted lines, as numbers.

You will have to extract these numbers one at a time to be used as the

index number for the layer list you used to populate the list_box (nth x LayList).

Next is to rebuild the list and repopulate the list_box.

 

I personally do not like to see any execution while the dialog box is open.

After the button is pressed, set a flag so that the dialog will close, the

program executes, then the dialog is reopened - looping as needed.

 

Hope this helps.

 


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

0 Likes
Message 3 of 44

john.uhden
Mentor
Mentor

All you have to do is to add the property "multiple_select = true" to the list_box tile definition.

Then when you select multiple items from the list you will get back a string like "1 3 5 8" which I think you can convert into a list of integers via something like...

(setq lst (read (strcat "(" str ")")))

which represent the item numbers in the list, but I don't remember if that's zero-based or not, but you'll figure it out.

If it's not then (setq lst (mapcar '1- lst))

John F. Uhden

0 Likes
Message 4 of 44

dalennea
Enthusiast
Enthusiast

Thanks so much for the help!  Really appreciated!  So here is the DCL information for the list box... I have modified as suggested:


: list_box { //define popup list
key = "layerlist"; //give it a name
height = 10;
width = 55;
multiple_select = true;
fixed_width_font = true;
allow_accept = true; //initial value

 

 

Here is the additional code for the function I am trying to fix as suggested up above... I am having problems with the Action Tile or other solution to follow what is suggested... So I can read the text file into the dialog box then I am trying to see how I implement the suggestions to have it as a string that I can run against another lsp function... essentially I want the user to select in the list box the items that will have to change layers...  (i.e. they select text1, text2, text3, text4 from the list box and then push a button to change those layers names to another layer (the button layer selection)... any help would be much appreciated... I have programmed it up to this point but am hitting a hurdle on understanding this... Thanks

 

 

(defun c:archi ( / result dcl_id)
(setq txtlist (list))
(setq openfile (open "c:/lsp/david.txt" "r")); reading the list
(while (setq line (read-line openfile))
(setq txtlist (append txtlist (list line)))
)
(close openfile)


(setq dcl_id (load_dialog "DCR_PROGRAM.dcl")); loading the DCL
(if (not (new_dialog "dcl_test" dcl_id))
(progn
(alert "The DCR PROGRAM.dcl file could not be loaded!")
(exit)
)
)

(progn

(start_list "layerlist")
(mapcar 'add_list txtlist); Adding the text to the layerlist box
(end_list)

(action_tile
"a-convert"
"(done_dialog)(setq result T)"
)
(start_dialog)
(unload_dialog dcl_id)
(if result
(der)
)
)
(princ)
)

 

 

0 Likes
Message 5 of 44

john.uhden
Mentor
Mentor

Just shooting from the hip, but here's a stab at it.

 

(defun @layerlist (str / lst)
  (foreach i (read (strcat "(" str ")"))
    (setq lst (cons (nth i txtlist) lst))
  )
  (reverse lst)
)
;
;
(action_tile "layerlist" "(setq layers (@layerlist $value))")

But careful there.  A popup_list is a different tile from a list_box.  I don't think you can multiple_select in a popup_list.

 

John F. Uhden

0 Likes
Message 6 of 44

dalennea
Enthusiast
Enthusiast

Thanks for the information... so in this case if I wanted to delete the layers that are selected from the list box I would pass the "layers" variable to the layer delete button ?  So a user will activate the list box and then highlight over the text (which is the layer list) that will be assigned to the "layers" value and then it would process that function ?  I am just checking to see if  I am processing the information correctly... I am such a nob... lol

0 Likes
Message 7 of 44

john.uhden
Mentor
Mentor

The "layerlist" action for now simply creates a list of the selected layers that came from txtlist.

What you do with the list is up to you.

F'rinstance you might have radio buttons for different actions, such as "Erase" "Freeze" "Off" "On" "Thaw" "Grip."

You would pick one and hit OK.

John F. Uhden

0 Likes
Message 8 of 44

dalennea
Enthusiast
Enthusiast

Again thanks... but for some reason it is not working....

0 Likes
Message 9 of 44

dalennea
Enthusiast
Enthusiast

Can you take a look at the syntax... perhaps you can see where I have erred... 

 

(defun c:archi ( / result dcl_id)
(setq txtlist (list))
(setq openfile (open "c:/lsp/david.txt" "r")); reading the list
(while (setq line (read-line openfile))
(setq txtlist (append txtlist (list line)))
)
(close openfile)


(setq dcl_id (load_dialog "DCR_PROGRAM.dcl")); loading the DCL
(if (not (new_dialog "dcl_test" dcl_id))
(progn
(alert "The DCR PROGRAM.dcl file could not be loaded!")
(exit)
)
)

(progn

(start_list "layerlist"); Adding the text to the layerlist box
(end_list)

(action_tile
"a-col"
"(done_dialog)(setq result T)"
)
(action_tile
"layerlist"
"(setq layers (@layerlist $value))"
)
(start_dialog)
(unload_dialog dcl_id)
(if result
(dal)
)
)
(princ)
)

0 Likes
Message 10 of 44

dalennea
Enthusiast
Enthusiast

(defun @layerlist (str / lst)
(foreach i (read (strcat "(" str ")"))
(setq lst (cons (nth i txtlist) lst))
)
(reverse lst)
)


(defun c:archi ( / result dcl_id)
(setq txtlist (list))
(setq openfile (open "c:/lsp/david.txt" "r")); reading the list
(while (setq line (read-line openfile))
(setq txtlist (append txtlist (list line)))
)
(close openfile)


(setq dcl_id (load_dialog "DCR_PROGRAM.dcl")); loading the DCL
(if (not (new_dialog "dcl_test" dcl_id))
(progn
(alert "The DCR PROGRAM.dcl file could not be loaded!")
(exit)
)
)

(progn

(start_list "layerlist"); Adding the text to the layerlist box
(end_list)

(action_tile
"a-col"
"(done_dialog)(setq result T)"
)
(action_tile
"layerlist"
"(setq layers (@layerlist $value))"
)
(start_dialog)
(unload_dialog dcl_id)
(if result
(dal)
)
)
(princ)
)

0 Likes
Message 11 of 44

john.uhden
Mentor
Mentor
It's time to post your code.

John F. Uhden

0 Likes
Message 12 of 44

dalennea
Enthusiast
Enthusiast

Here is the code...I am have the "Convert active as the trigger for the Action Tile...

 

right now with this I get the  error: bad argument type: consp nil 

 

Lisp

(defun c:archi ( / result dcl_id)
(setq txtlist (list))
(setq openfile (open "c:/lsp/david.txt" "r")); reading the list
(while (setq line (read-line openfile))
(setq txtlist (append txtlist (list line)))
)
(close openfile)


(setq dcl_id (load_dialog "DCR_PROGRAM.dcl")); loading the DCL
(if (not (new_dialog "dcl_test" dcl_id))
(progn
(alert "The DCR PROGRAM.dcl file could not be loaded!")
(exit)
)
)

(progn

(start_list "layerlist")
(mapcar 'add_list txtlist); Adding the text to the layerlist box
(end_list); end list

(action_tile
"a-convert"
(strcat
"(progn
(setq layt (get_tile \"layerlist\"))"
"(done_dialog) (setq userclick T))"
)
)
(start_dialog)
(unload_dialog dcl_id)
)
(if userclick
(progn
(setq layt (nth i layerlist))
(alert (strcat "You Selected: " layt))
)
)
(princ)
)

 

 

DCL 

 

 

//---------------------------------------------------------------------------------------------------------
// Architectural Layers Conversion Program - Dialog Box
//---------------------------------------------------------------------------------------------------------
dcl_test : dialog { //dialog name
label = "Architectural Layers Conversion Program - Alpha" ;//give it a label

:boxed_radio_column { //define radio column
label = "Architectural Layers Program" ; //give it a label

: button { //define radion button
key = "a-convert" ; //give it a name
label = "Convert Drawing to Architectural Layers " ; //give it a label
value = "1" ; //switch it on
} //end definition
}
: row {

:boxed_radio_column { //define radio column
label = "Architectural Layers Layers" ; //give it a label

: button { //define radion button
key = "a-col" ; //give it a name
label = "A-COL" ; //give it a label
value = "1" ; //switch it on
} //end definition

: button { //define radio button
key = "a-door" ; //give it a name
label = "A-DOOR" ; //give it a label
} //end definition

: button { //define radio button
key = "a-flor-strs" ; //give it a name
label = "A-FLOR-STRS" ; //give it a label
} //end definition

: button { //define radio button
key = "a-furn" ; //give it a name
label = "A-FURN" ; //give it a label
} //end definition

: button { //define radio button
key = "a-mod-pnl" ; //give it a name
label = "A-MOD-PNL" ; //give it a label
} //end definition

: button { //define radion button
key = "a-mod-wksf" ; //give it a name
label = "A-MOD-WKSF" ; //give it a label
}
//end definition
: button { //define radion button
key = "a-mod-wall" ; //give it a name
label = "A-WALL" ; //give it a label
} //end definition
: button { //define radion button
key = "a-mod-wind" ; //give it a name
label = "A-WIND" ; //give it a label
} //end definition
} //end radio column


: boxed_column { //define boxed column
label = "&Layers not converted"; //give it a label

: list_box { //define popup list
key = "layerlist"; //give it a name
height = 10;
width = 55;
multiple_select = true;
fixed_width_font = true;
allow_accept = true; //initial value

} //end list

} //end boxed column

} //end row

: row {
fixed_width = true;
label = "Progress Bar";
key = "br-label";
: row {
: button {
key = "convert";
label = "Convert";
mnemonic = "T";
key = "cancel";
is_cancel = true;
}
}
: row {
: button {
key = "delete";
label = "Delete Layer";
mnomonic = "E";
is_cancel = true;
}
}

: row {
: button {
key = "ok";
label = "Ok";
mnomonic = "k";
is_cancel = true;
}
}

: row {
: button {
key = "ccancel";
label = "Cancel";
mnomonic = "a";
is_cancel = true;
}
}

: image {
key = "progbar";
fixed_width = 300;
height = 3;
}
/// This Tile may also be put below the OK_Cancel buttons

: row {
: errtile {
label = "";
key = "error";
width = 26;
}
}
}


: text_part { //define text
label = "Developed"; //give it some text
} //end text

: text_part { //define more text
label = "by the Phantom"; //some more text
} //end text


} //end dialog

0 Likes
Message 13 of 44

scot-65
Advisor
Advisor

You are using a boxed radio column.

This is a container for the radio buttons. Assign this container a key = "RadCol".

 

>> :boxed_radio_column { //define radio column
>> label = "Architectural Layers Layers" ; //give it a label

>> : button...

This last line should read :radio_button. It will make reading code easier.

 

Now when you select the Process button, grab the value from the radio_column

and the value for the list_box:

 

(action_tile "br-label" "(setq a (get_tile \"RadCol\"))(setq b (get_tile \"LayLst\"))(done_dialog 2)")

 

Notice the function action_tile contains a pair of quotes? Two and exactly 2 pair are allowed

between the opening and closing parenthesis. For any additional quotes that may be needed,

you have to escape them \" or send out to a function/subroutine.

 

Fetching tile values can only occur when the dialog is open - meaning values are present

only when your code to grab the values is in between (new_dialog) and (start_dialog).

 

The value of RadCol will determine which COND to take.

 

Another hint is when you start processing the list of integers (FOREACH x ...)

if the line number is NOT a MEMBER build a new temporary layer list CONS and

repopulate the list box.

 


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

0 Likes
Message 14 of 44

dalennea
Enthusiast
Enthusiast

Thanks for the explanation... could you modify the code so that I can see the application of what you are saying... it would really help...

0 Likes
Message 15 of 44

john.uhden
Mentor
Mentor

Okay, you're learning.  At least you are learning in the right place.

You have the a_covert button action doing...

(setq layt (get_tile \"layerlist\"))

Yet, after the userclick you are doing...

(if userclick
(progn
(setq layt (nth i layerlist))

 

layt already has a value, but layerlist does not, nor does i.

And what is the point of setting multiple_select=true if you are going to select only one item from the list?

Before anyone just writes you the solution, please think about what I've pointed out.

Hint:  I don't know why/how I came up with this, but I think every tile (that can take an action) should have an action associated with it.  That's why I posted earlier about (action_tile "layerlist" ...) to get the list of layers (plural) selected, not just one.  I'm not sure if using (get_tile "layerlist") will return the list of items selected in that box.

Also, I have always had the habit of using the construct...

(action_tile "accept" "(done_dialog 1)")

(action_tile "cancel" "(done_dialog 0)")

(setq action (start_dialog))

   [presuming you have an ok_cancel_errtile]

So if "accept" was clicked then action would be 1, and I would know whether to continue or not.

John F. Uhden

0 Likes
Message 16 of 44

dalennea
Enthusiast
Enthusiast

Thanks for the information and explanation.  I have not worked with Dialog Boxes in years and am getting re-introduced.  I have re-read your information in previous messages and think that I have it correct now... after I have "!layers" I can see the correct values are now showing up after I have selected them in the dialog box... Using this snippet of  code .... (defun @layerlist (str / lst)
(foreach i (read (strcat "(" str ")"))
(setq lst (cons (nth i txtlist) lst))
)
(reverse lst)
)

and 

 

(action_tile "layerlist" "(setq layers (@layerlist $value))")

 

This produces the selection... so I have two questions... I want to use the value of "layers" to then set an action against.  Like I want to change the value of "layers" to rename those layers to another layer or even create/delete a layer.  I am running into the challenge of how to use that value to accomplish that... for instance... let's say I want to use that value to delete the layer selected...so I selected the values in the listbox and then it identifies those names (I have checked to see if that is so by "!layers) and now that value is set to "layers" and now I want to do the following:

 

(defun dal ()
(command "-laydel" "n" layers "" "y")
)

 

 

Evidently I am going wrong somewhere on the syntax... 

0 Likes
Message 17 of 44

john.uhden
Mentor
Mentor
Yes! You've got the idea of multiple selection!
Now follow the rest of my advice re: ok_cancel_errtile,
and then ...
(setq action (start_dialog))
;; unload dialog
(cond
((/= action 1)) ;; do nothing
((= choice "Delete")
(foreach layer layers (command "-laydel" "n" layer "" "y"))
)
((= choice "Rename" ...)
(etc.)
)

John F. Uhden

0 Likes
Message 18 of 44

dalennea
Enthusiast
Enthusiast

Hmmm... what did I do wrong here.... 

 

 

(action_tile "layerlist" "(setq layers (@layerlist $value))")
(action_tile "accept" "(done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(setq action (start_dialog))
(cond
((/= action 1)) ;; do nothing
((= choice "Delete"))
(foreach layer layers (command "-laydel" "n" layer "" "y"))
)

 

0 Likes
Message 19 of 44

dalennea
Enthusiast
Enthusiast

I get invalid layer name... 

0 Likes
Message 20 of 44

dalennea
Enthusiast
Enthusiast

Does it have something to do with the spaces from the list ?  When I look at the layer selection... it seems to have spaces in it...

0 Likes