TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: V-Man on July 16, 2004, 09:27:55 AM

Title: List_box Multiple_select
Post by: V-Man on July 16, 2004, 09:27:55 AM
I'm working on this lisp and I'm a little stumped. This lisp works with a
dialog box (list_box)(with multiple_select option) to select 1 or more
than 1 item in the list and then pass the findings to a variable and eventually
start the (mtext) command, Ask the user mtext starting point and place
in mtext the findings from the selected list_box values.

Can someone aid me with this prob.

Thanks,

This is from Kenny's. Thanks.

Code: [Select]

(defun C:Test ()
(setq NAMES '("01Monday" "02Tuesday" "Wednesday" "Thursday""Friday" "Saturday" "Sunday"))
(setq dcl_id (load_dialog "popup.dcl"))
(if (not (new_dialog "popup" dcl_id)
)
(exit)
)
(start_list "selections")
(mapcar 'add_list NAMES)
(end_list)
(action_tile "accept"
(strcat "(getans)"
"(done_dialog) (setq userclick T)")
)
(action_tile "cancel"
"(done_dialog) (setq userclick nil)"
)
(start_dialog)
(unload_dialog dcl_id)
(if userclick
(progn
(setq SIZ (fix SIZ))
(setq SIZ (nth SIZ NAMES))
(alert (strcat "You Selected: " SIZ))
)
)
(princ)
)


This basically works great but I want it to be able to display
(i.e. In Mtext format if the user select both 01Monday & 02Tuesday


In the drawing...

01Monday
02Tuesday

2 seperate lines per entry
Title: List_box Multiple_select
Post by: V-Man on July 16, 2004, 09:32:42 AM
I forgot this part of the code.

Code: [Select]

(defun getans ();;get values of controls & close the dialog
  (setq SIZ (atof (get_tile "selections")))
  (done_dialog 0)
)
Title: List_box Multiple_select
Post by: Columbia on July 16, 2004, 10:43:52 AM
Okay.  There are a couple of things to address with this.  So here it goes.

1.)  the DCL control listbox returns a couple of different things depending on multiple select, when it is actioned, by either "action_tile" or "get_tile".  When multiple_select=false; then the value of the listbox is a string containing the integer relative to the selected index (i.e. "3" for the 4th item in the list) or "" (empty string) if none are selected.  When multiple_select=true; then the value returns the same as above when only one item is selected, however it returns a single string with all chosen indices concatenated delimited with spaces (i.e. "1 2 3" for the 2 thru 4 items selected).
[Are you following me so far?  Good...]
So what you need to do is take the value, parse out the indices, and have them refer back to your first list "NAMES".

2.) Then once you have the items of the list "NAMES" that you want, then you need to concatenate those values using a "\\P" between each to signify you want a new line.

Try that, and if you need help with the actual code, let us know...
Title: List_box Multiple_select
Post by: V-Man on July 16, 2004, 11:27:33 AM
Even with my routine I cannot get it to return the multiple selections.
Title: List_box Multiple_select
Post by: SMadsen on July 16, 2004, 12:00:00 PM
Dvarino, here's a small test with a multiple_select list box:

Code: [Select]

// DCL
popup : dialog {
  : list_box {
    key = "selections";
    multiple_select = true;
  }
  ok_cancel;
}

;; AutoLISP
(defun C:Test ()
  (setq NAMES '("01Monday"     "02Tuesday"    "Wednesday"
                "Thursday"     "Friday"       "Saturday"
                "Sunday"
               )
  )
  (setq dcl_id (load_dialog "popup.dcl"))
  (if (not (new_dialog "popup" dcl_id))(exit))
  (start_list "selections")
  (mapcar 'add_list NAMES)
  (end_list)
  (action_tile "selections" "(setq strLst (setItems $value NAMES))")
  (setq userclick (start_dialog))
  (unload_dialog dcl_id)
  (and (= 1 userclick)
       (and strLst (princ strLst))
  )
  (princ)
)

(defun setItems (val lst / ret)
  (foreach n (mapcar (function (lambda (n) (- n 48)))
                     (vl-remove 32 (vl-string->list val))
             )
    (setq ret (cons (nth n lst) ret))
  )
  (reverse ret)
)


It should return a list of the items that were chosen. If you don't like the MAPCAR thingie then the help files shows an alternative way of parsing the value of a multiple_select list box. It's in the section Managing Dialog Boxes -> List Boxes and Pop-up Lists -> Processing List Elements and is called MK_LIST.
Title: List_box Multiple_select
Post by: V-Man on July 16, 2004, 02:36:48 PM
Thanks for the help but for some reason my list is a lot larger and it does not return the selected items.

Code: [Select]

    (setq agencynames '("01  Monday"     "02  Tuesday"    "03  Wednesday"
                  "04  Thursday"     "05  Friday"       "06  Saturday"
                  "07  Sunday" "xx  This" "xx  Does" "xx  Not" "xx Work"
               )
    )


If you try this multiple times using different scenarios you will see that it is not reporting what was selected.
Title: List_box Multiple_select
Post by: SMadsen on July 16, 2004, 07:54:22 PM
Wow, that was somewhat of a blooper! Sorry. I must have fallen asleep while writing that.

Did you try the MK_LIST in the help files instead?
Title: List_box Multiple_select
Post by: Kerry on July 17, 2004, 07:37:39 PM
The multiselect method you are instigating may not suit the functionality you are trying to develop. The list returned from the get_tile call will be sorted numerically, not in selection sequence as you may expect.

This code may  be the simplest to return a list of values from the type of  string returned by the multiple selection list_box.
(setq tmp "2 4 6 9")
(read (strcat "(" tmp ")"))  ;; ==>> (2 4 6 9)

;;-----

The first listing attached will do what you ask for .. multiple and single selection are valid.

The second listing will do what I think you want.

The third listing is some library stuff , plus the DCL

Code: [Select]

;;; Multiple Selection
;;;
(defun c:test0718b (/             dcl_id        index         names
                    starter       programpath   returnlist    objmtext
                    ;;
                    *error*       action-cancel do-something  action-accept
                   )
  ;;-----
  (defun *error* (msg) (kbsf:debug-simple-error msg))
  (defun action-cancel (/) (princ))
  (defun do-something (/)
    (alert (strcat "You Selected: " returnlist))
    (setq objmtext (vla-addmtext kbsg:modelspace
                                 (vlax-3d-point '(0 0 0))
                                 0.0
                                 returnlist
                   )
    )
  )
  (defun action-accept (/ tmp tmpstr)
    (if (and (setq tmp (get_tile "selections"))
             (setq tmpstr     ""
                   returnlist (vl-string-right-trim
                                "\\P"
                                (foreach item (read (strcat "(" tmp ")"))
                                  (setq tmpstr (strcat tmpstr (nth item names) "\\P"))
                                )
                              )
             )
        )
      (done_dialog 101)
      (done_dialog 0)
    )
  )
  ;;-----
  ;;-----
  (setq programpath "z:\\_test\\List_box_Multiple_select\\"
        names       '("01 Monday"      "02 Tuesday"     "03 Wednesday"
                      "Thursday"       "Friday"         "Saturday"
                      "Sunday"         "08 Day Off"
                     )
  )
  (if
    (not
      (new_dialog "dcl0718multiple"
                  (setq dcl_id (load_dialog (strcat programpath "dcl0718.dcl")))
      )
    )
     (exit)
  )
  ;; -- initialise
  (start_list "selections")
  (mapcar 'add_list names)
  (end_list)
  (action_tile "accept" "(action-accept)")
  (setq starter (start_dialog))
  ;; --
  (unload_dialog dcl_id)
  (cond ((= starter 101) (do-something))
        ((<= starter 0) (action-cancel))
  )
  (princ)
)

Code: [Select]

;;;
;;;
;;; Selection in sequence

(defun c:test0718c (/ dcl_id          names           newstring
                      objmtext        programpath     starter
                      ;;
                      *error*         make-selection  action-cancel
                      do-something    action-accept
                     )
  (defun *error* (msg) (kbsf:debug-simple-error msg))
  (defun make-selection (val /)
    (setq newstring (strcat newstring (nth (atoi val) names) "\\P"))
    (set_tile "newstring" newstring )
  )
  (defun action-cancel (/) (princ))
  (defun do-something (/)    
    (setq objmtext (vla-addmtext kbsg:modelspace
                                 (vlax-3d-point '(0 0 0))
                                 0.0
                                 newstring
                   )
    )
  )
  (defun action-accept (/ tmp tmpstr)
    (if (and (/= "" newstring)
             (setq newstring (vl-string-right-trim "\\P" newstring))
        )
      (done_dialog 101)
      (done_dialog 0)
    )
  )
  ;;-----
  ;;-----
  (setq programpath "z:\\_test\\List_box_Multiple_select\\"
        names       '("01 Monday"      "02 Tuesday"     "03 Wednesday"
                      "Thursday"       "Friday"         "Saturday"
                      "Sunday"         "08 Day Off"
                     )
        newstring   ""
  )
  (if
    (not
      (new_dialog "dcl0718single"
                  (setq dcl_id (load_dialog (strcat programpath "dcl0718.dcl")))
      )
    )
     (exit)
  )
  ;; -- initialise
  (start_list "selections")
  (mapcar 'add_list names)
  (end_list)
  (action_tile "selections" "(make-selection $value )")
  (action_tile "accept" "(action-accept)")
  (setq starter (start_dialog))
  ;; --
  (unload_dialog dcl_id)
  (cond ((= starter 101) (do-something))
        ((<= starter 0) (action-cancel))
  )
  (princ)
)


LIBRARY STUFF
Code: [Select]

(vl-load-com)
(setq kbsg:debug_on t)
(or kbsg:acadapp (setq kbsg:acadapp (vlax-get-acad-object)))
(or kbsg:activedoc (setq kbsg:activedoc (vla-get-activedocument kbsg:acadapp)))
(or kbsg:modelspace (setq kbsg:modelspace (vla-get-modelspace kbsg:activedoc)))
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------
;;;
(defun kbsf:debug-simple-error (msg / tmp)
  ;;----- Cancel any Active Commands -----------------------------
  (while (< 0 (getvar "cmdactive")) (command))
  (setvar "menuecho" 1)
  (vla-endundomark kbsg:activedoc)
  ;;----- Display error message if applicable
  (cond
    ((not msg))
    ((member (strcase msg t)
             '("console break" "function cancelled" "quit / exit abort")
     )
    )
    ((princ (strcat "\nApplication Error: " (itoa (getvar "errno")) " :- " msg))
    )
  )
  (setvar "errno" 0)
  ;;----- Display backtrace
  (vl-bt)
  ;;----- Release Bound Activex Objects
  ;;  --- removed
  ;;----- Reset System Variables from global list
  ;;  --- removed
  ;;-----
  (princ)
)
;;;------------------------------------------------------------------
;;;------------------------------------------------------------------

Code: [Select]

// dcl0718.dcl
dcl0718single
: dialog
{
label = "Test list_box" ;
: list_box
{
key = "selections" ;
multiple_select = false ;
}
: text
{
key = "newstring" ;
fixed_width = true ;
width = 70 ;
}

ok_cancel ;
}

dcl0718multiple
: dialog
{
label = "Test list_box" ;
: list_box
{
key = "selections" ;
multiple_select = true ;
}
ok_cancel ;
}
Title: List_box Multiple_select
Post by: V-Man on July 19, 2004, 08:48:57 AM
Quote

The multiselect method you are instigating may not suit the functionality you are trying to develop. The list returned from the get_tile call will be sorted numerically, not in selection sequence as you may expect.

This code may be the simplest to return a list of values from the type of string returned by the multiple selection list_box.
(setq tmp "2 4 6 9")
(read (strcat "(" tmp ")")) ;; ==>> (2 4 6 9)

;;-----

The first listing attached will do what you ask for .. multiple and single selection are valid.

The second listing will do what I think you want.

The third listing is some library stuff , plus the DCL



This is exactly what I want. Thanks for the hard work.
Title: List_box Multiple_select
Post by: V-Man on July 19, 2004, 08:51:19 AM
How do you make it so that it asks the use to 'pick a point' to place the Mtext in stead of it places it at 0,0??
Title: List_box Multiple_select
Post by: Anonymous on July 19, 2004, 10:01:04 AM
Perhaps something like this :
Code: [Select]

  (defun do-something (/ workpoint )
    (initget 1)
    (setq
      workpoint (getpoint "\n Specify MText insertion point : ")
      objmtext (vla-addmtext kbsg:modelspace
                                 (vlax-3d-point workpoint)
                                 0.0
                                 newstring
                   )
    )
  )
Title: List_box Multiple_select
Post by: Kerry on July 19, 2004, 10:03:52 AM
Woops, not logged in :(

Just replace the do-something procedure with the one I posted should do the trick.
Title: List_box Multiple_select
Post by: V-Man on July 19, 2004, 10:31:28 AM
I get this when i run the routine.

[0.77] (VL-BT)
[1.73] (KBSF:DEBUG-SIMPLE-ERROR "ActiveX Server returned an error: Parameter
not optional")
[2.68] (*ERROR* "ActiveX Server returned an error: Parameter not optional")
[3.63] (_call-err-hook #<SUBR @0cbb9f50 *ERROR*> "ActiveX Server returned an
error: Parameter not optional")
[4.57] (sys-error "ActiveX Server returned an error: Parameter not optional")
:ERROR-BREAK.52 nil
[5.49] (intelligent-invoke #<VLA-OBJECT IAcadModelSpace 0dc12c84> "AddMText" 1
#<variant 8197 ...> 0.0 nil)
[6.39] (#<SUBR @02674dd4 vlax-invoke-method> #<VLA-OBJECT IAcadModelSpace
0dc12c84> "AddMText" #<variant 8197 ...> 0.0 nil)
[7.31] (vla-AddMText #<VLA-OBJECT IAcadModelSpace 0dc12c84> #<variant 8197 ...>
0.0 nil)
[8.23] (DO-SOMETHING)
[9.19] (C:TESTB)
[10.15] (#<SUBR @0cbbe730 -rts_top->)
[11.12] (#<SUBR @026f2334 veval-str-body> "(C:TESTB)" T #<FILE internal>)
:CALLBACK-ENTRY.6 (:CALLBACK-ENTRY)
:ARQ-SUBR-CALLBACK.3 (nil 0)
[/list:u]
Title: List_box Multiple_select
Post by: SMadsen on July 19, 2004, 10:34:16 AM
Quote from: Kerry Brown
(setq tmp "2 4 6 9")
(read (strcat "(" tmp ")"))  ;; ==>> (2 4 6 9)

That's a pearl! I'm gonna steal that, Kerry.
Title: List_box Multiple_select
Post by: Kerry on July 19, 2004, 10:47:00 AM
's ok, steal away Stig.  Just glad I have to have something worth borrowing ..


dvarino :

[7.31] (vla-AddMText #<VLA-OBJECT IAcadModelSpace 0dc12c84> #<variant 8197 ...>  0.0 nil )

indicate to me that the string is nil.
Any chance you tried the procedure as a stand alone :D

... if so, set the newstring value as a glogal variable to the text you want to add.
Title: List_box Multiple_select
Post by: Kerry on July 19, 2004, 10:52:47 AM
Oh, i had another look at the error trace

[9.19] (C:TESTB)
.. means you called it from a routine.
You may have to repost the FULL routine for me to have a guess.   .. seems the newstring variable is not being set , and that shouldnt happen, cause the action--accept procedure tests for its value before closing the dialog.

kwb
Title: List_box Multiple_select
Post by: Kerry on July 19, 2004, 10:56:08 AM
PS :

See how handy the  (VL-BT) function is !!

I always use that style of error trap for testing .. it has got me out of the poo a few times now.
Title: List_box Multiple_select
Post by: V-Man on July 19, 2004, 10:59:20 AM
It seems to work with the single selection but the multiple selection is the one giving the error.
Title: List_box Multiple_select
Post by: Kerry on July 19, 2004, 11:12:00 AM
Cant fault it here .. weird

try this in the c:test0718c  :
Code: [Select]

  (defun do-something (/ workpoint )
    (alert (strcat "Temporary Debug \n" "You Selected: " newstring))  ;; temporary Debug
    (initget 1)
    (setq
      workpoint (getpoint "\n Specify MText insertion point : ")
      objmtext (vla-addmtext kbsg:modelspace
                                 (vlax-3d-point workpoint)
                                 0.0
                                 newstring
                   )
    )
  )
Title: List_box Multiple_select
Post by: V-Man on July 19, 2004, 11:45:15 AM
Now I get this....

[0.58] (VL-BT)
[1.54] (KBSF:DEBUG-SIMPLE-ERROR "bad argument type: stringp nil")
[2.49] (*ERROR* "bad argument type: stringp nil")
[3.44] (_call-err-hook #<SUBR @0cbbc618 *ERROR*> "bad argument type: stringp
nil")
[4.38] (sys-error "bad argument type: stringp nil")
:ERROR-BREAK.33 nil
[5.30] (STRCAT "Temporary Debug \n" "You Selected: " nil)
[6.23] (DO-SOMETHING)
[7.19] (C:TESTB)
[8.15] (#<SUBR @0cbbcde8 -rts_top->)
[9.12] (#<SUBR @026f2334 veval-str-body> "(C:TESTB)" T #<FILE internal>)
:CALLBACK-ENTRY.6 (:CALLBACK-ENTRY)
:ARQ-SUBR-CALLBACK.3 (nil 0)
[/list:u]
Title: List_box Multiple_select
Post by: Kerry on July 19, 2004, 11:50:45 AM
ok, GOOD, it gets easier from here ..

The newstring variable is obviously the culpret. Can you post the c:TESTB function ??
Title: List_box Multiple_select
Post by: V-Man on July 19, 2004, 12:15:39 PM
Here you go..

Code: [Select]

(defun c:testb (/             dcl_id        index         names
                    starter       programpath   returnlist    objmtext
                    ;;
                    *error*       action-cancel do-something  action-accept
                   )
  ;;-----
  (defun *error* (msg) (kbsf:debug-simple-error msg))
  (defun action-cancel (/) (princ))
      (defun do-something (/ workpoint )
        (alert (strcat "Temporary Debug \n" "You Selected: " newstring))  ;; temporary Debug
        (initget 1)
        (setq
          workpoint (getpoint "\n Specify MText insertion point : ")
          objmtext (vla-addmtext kbsg:modelspace
                                     (vlax-3d-point workpoint)
                                     0.0
                                     newstring
                       )
        )
  )
  (defun action-accept (/ tmp tmpstr)
    (if (and (setq tmp (get_tile "selections"))
             (setq tmpstr     ""
                   returnlist (vl-string-right-trim
                                "\\P"
                                (foreach item (read (strcat "(" tmp ")"))
                                  (setq tmpstr (strcat tmpstr (nth item names) "\\P"))
                                )
                              )
             )
        )
      (done_dialog 101)
      (done_dialog 0)
    )
  )
  ;;-----
  ;;-----
  (setq programpath "c:\\don\\download\\notes\\"
        names       '("01 Monday"      "02 Tuesday"     "03 Wednesday"
                      "Thursday"       "Friday"         "Saturday"
                      "Sunday"         "08 Day Off"
                     )
  )
  (if
    (not
      (new_dialog "dcl0718multiple"
                  (setq dcl_id (load_dialog (strcat programpath "test5.dcl")))
      )
    )
     (exit)
  )
  ;; -- initialise
  (start_list "selections")
  (mapcar 'add_list names)
  (end_list)
  (action_tile "accept" "(action-accept)")
  (setq starter (start_dialog))
  ;; --
  (unload_dialog dcl_id)
  (cond ((= starter 101) (do-something))
        ((<= starter 0) (action-cancel))
  )
  (princ)
)
Title: List_box Multiple_select
Post by: Kerry on July 19, 2004, 12:22:59 PM
In the  do-something procedure for the c:testb function

replace newstring with returnlist , which is the concatenated string for that function.

regards.Kerry
Title: List_box Multiple_select
Post by: V-Man on July 20, 2004, 04:31:49 PM
I'm looking the the help files and I cannot find where in vlisp can you set the height of mtext items created in vlisp.

Is this possible?
Title: List_box Multiple_select
Post by: Kerry on July 20, 2004, 05:15:28 PM
Yes. Have a play with this.

Code: [Select]

  (defun do-something (/ workpoint )
    (alert (strcat "Temporary Debug \n" "You Selected: " newstring))  ;; temporary Debug
    (initget 1)
    (setq
      workpoint (getpoint "\n Specify MText insertion point : ")
      objmtext (vla-addmtext kbsg:modelspace
                                 (vlax-3d-point workpoint)
                                 0.0
                                 newstring ;; or returnlist depending on module
                   )
    )
    (vla-put-Height objmtext 50.0)
  )