Selecting previous after text edition & reactor

Selecting previous after text edition & reactor

msarqui
Collaborator Collaborator
1,200 Views
10 Replies
Message 1 of 11

Selecting previous after text edition & reactor

msarqui
Collaborator
Collaborator

Hi guys,


After use the ATTIPEDIT or the TEXTEDIT commands in a block with attributes, the selected block will not “be” on the previous AutoCAD selection set. I mean, after use one of these commands, if I try to MOVE, PREVIOUS, AutoCAD will say: “No previous selection set”
So I tried:

(setq nsel (nentsel))
(command ".attipedit" nsel)
(while (/= 0 (getvar 'cmdactive)) (command pause))


But the problem is, I am using this in a reactor and the “command” can’t be called.
So I tried:

(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(setq nsel (nentsel))
(vla-SendCommand doc (strcat ".attipedit nsel"))
(vla-SendCommand doc (strcat "(while (/= 0 (getvar 'cmdactive)) (command pause))"))


But also without success…

 

My questions are:
1. Is there a way to put the selected block by the ATTIPEDIT or the TEXTEDIT in a selection set?
2. Can the reactor be paused without “command” to wait for the user interaction?

 

Thanks

Marcelo

0 Likes
1,201 Views
10 Replies
Replies (10)
Message 2 of 11

dbroad
Mentor
Mentor

These are your questions and answers

Q1. Is there a way to put the selected block by the ATTIPEDIT or the TEXTEDIT in a selection set?

A1: Not exactly but a reactor callback could be triggered by the modification of the attibute.  During that callback data on the attibute could be added to the reactor data list using vlr-data-set for later use.  The data would be for the attribute.  To get the "insert" of the attribute, you would need to obtain the entity information of the attibute and then access the 330 pointer to the insert entity.
Q2. Can the reactor be paused without “command” to wait for the user interaction?

A2: No.  You must let the command finish.  A vlr-command-reactor could track the :vlr-command-ended event and perform processes necessary for a followup command.  No reactor callback however can actually issue a command.

 

Your situation requires a vlr-command-reactor :vlr-command-will-start event/callback to look for those two commands and to add the acdb reactor and reactor to track the end of the command, a vlr-acdb-reactor :vlr-objectmodified callback to track which objects are modified during the commands and a vlr-command-reactor with a :vlr-command-ended event/callback pair to remove the reactors added during the commands. In the end, you would have the objects modified as a list of data attached to the reactor which you could obtain with a vlr-data function.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 3 of 11

msarqui
Collaborator
Collaborator

@Anonymous wrote:

 

 

Your situation requires a vlr-command-reactor :vlr-command-will-start event/callback to look for those two commands and to add the acdb reactor and reactor to track the end of the command, a vlr-acdb-reactor :vlr-objectmodified callback to track which objects are modified during the commands and a vlr-command-reactor with a :vlr-command-ended event/callback pair to remove the reactors added during the commands. In the end, you would have the objects modified as a list of data attached to the reactor which you could obtain with a vlr-data function.


Hi dbroad,

Thanks for your answer. I was hoping the solution would be more simple. I say this because my knowledge in lisp is limited and I have no idea how to do what you explained. Would you mind posting a start point for me, please?

0 Likes
Message 4 of 11

dbroad
Mentor
Mentor

Before I do, open up vlide and use the vlide help to look up help on vlr-command-reactor, vlr-acdb-reactor, vlr-remove, vlr-add, vlr-data, and vlr-data-set.  For those, look carefullly at the arguments including the callback functions and their arguments.  Then look over the Reactor Functions Refeference.  Do a search on this newsgroup for reactors.  Then look at my explanation and give it a try and post what you attempt.  I suggest you initially make every callback a vlr-trace-reactor and look at the vlr-trace-window as you run your commands.

 

We'll take it from there after you've done your research.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 5 of 11

msarqui
Collaborator
Collaborator
Thanks dbroad

I will try. I will feed you back later...
0 Likes
Message 6 of 11

msarqui
Collaborator
Collaborator

I have been reading the help and some posts and so far I have no idea what I am doing, and my Vlide editor stopped working.
Sorry but it is too much for my understanding.

 

 

;http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/autoselect-layer-for-dimensions-autocad-2014/td-p/4313879
(defun CommandReactor:EditText ()
(or *CommandReactor*
(setq *CommandReactor* (vlr-command-reactor nil '(
	(:vlr-commandended . CommandReactor:CommandEnded)
	(:vlr-commandwillstart . CommandReactor:CommandWillStart)
						)
			)
);setq
);or
)
;;;--------------------------------------------------------------------;
(defun CommandReactor:CommandEnded (rea cmd)
(if *CommandReactor*
	(vlr-remove *CommandReactor*)
);if
(untst)
(princ)
)
;;;--------------------------------------------------------------------;
(defun CommandReactor:CommandWillStart (rea cmd)
(if	(wcmatch (strcase (car cmd)) "*ATTIPEDIT*,*TEXTEDIT*")
	(tst)
);if
)

(defun EditText ( / nsel dxf ename vlobj effname entg blk)
(setq nsel (nentsel))
(vl-cmdf ".attipedit" nsel)
(setq dxf (entget (car nsel)))					;Get the DXF list of that block
(setq ename (cdr (assoc 330 dxf)))				;Get the ENTITY NAME of the block
(setq vlobj (vlax-ename->vla-object ename))			;Convert to VLA-OBJECT
(setq effname (vla-get-EffectiveName vlobj))			;Get the EFFECTIVE NAME
(if	(= "ATTRIB" (cdr (assoc 0 (setq entg (entget (setq blk (entnext ename)))))))
	(alert "\nYou were able to edit the text with the reactor")
)
)

;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/vlr-acdb-reactor-vlr-objectmodified-autocad-2014-crashes-after/td-p/4574753
(defun tst ()
(setq myreactor
       (vlr-acdb-reactor nil '((:vlr-objectModified . RBS_ObjectModified)))
);setq
);defun

(defun RBS_ObjectModified (rctr objct)
(EditText)
)

(defun untst () ;to turn your reactor off (untst)
(vlr-remove myreactor))

 

0 Likes
Message 7 of 11

dbroad
Mentor
Mentor

Based on your level of effort evident in your response, I would say that any attempt to use reactors would be the wrong approach for you.  Being able to use reactors appropriately requires a curious mind that doesn't mind tinkering to get results.  It can't be appropriated by just copying reactor examples.  At the minimum, you need to be able to write expressions that have the correct number of arguments.

 

For you, I would suggest just using your main program which is reposted below.  Save the results of the nentsel.  Nentsel returns the nested entity (the attribute followed by the picked point.  Obtain the nested entities information with entget and then access the insert it is contained by accessing the 330 code.  Save the insert ename and, then if you want, use it at the end of your routine to set the previous selection set.  I removed the comments because they were either incorrect or obvious and not necessary.

 

What you have:

(defun EditText ( / nsel dxf ename vlobj effname entg blk)
(setq nsel (nentsel))
(vl-cmdf ".attipedit" nsel)
(setq dxf (entget (car nsel)))					
(setq ename (cdr (assoc 330 dxf)))				
(setq vlobj (vlax-ename->vla-object ename))			
(setq effname (vla-get-EffectiveName vlobj))			
(if
  (= "ATTRIB"
     (cdr(assoc 0 (setq entg (entget (setq blk (entnext ename)))))))
	(alert "\nYou were able to edit the text with the reactor")
)
)

What you should have written:

;;D. C. Broad, Jr.  1/3/2017
(defun C:EditAtt ( / ns ai ie ss) (setq ss (ssadd)) (while (setq ns (nentsel)) ;attribute and pick point (setq ai (entget (car ns));attribute ie (cdr(assoc 330 ai));block ) (command "_.attipedit" ns) (ssadd ie ss);blocks edited ) (sssetfirst ss ss) ;set up pickfirst set. (princ);exit quietly )

If you can't even bother to get vlide to run correctly, then you might consider hiring someone to help you with customization.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 8 of 11

Ranjit_Singh
Advisor
Advisor

AutoCAD commands can't be called in reactor callback functions. See if the below code is helpful. The routine will result in a selection set ss1. I had to keep this a global variable so you can use it in AutoCAD.

If you know exactly what you wan to do with the selection set then setup a end command reactor and manipulate ss1 as needed in the callback function.

 

(vl-load-com)
(defun removereactor  (data)
  (mapcar '(lambda (x)
             (if (wcmatch (vlr-data x) "attipeditwascalled,attipeditwasended")
               (vlr-remove x)))
          (cdar data)))
(if (vlr-reactors :vlr-command-reactor)
  (removereactor (vlr-reactors :vlr-command-reactor)))
(vlr-command-reactor "attipeditwascalled" '((:vlr-commandWillStart . funcone)))
(defun funcone  (reacobj paramlist / att attstr)
  (cond ((= (car paramlist) "ATTIPEDIT")
         (setq ss1 (ssadd))
         (while (and (setq att (nentsel)) (= (cdr (assoc 0 (entget (car att)))) "ATTRIB"))
           (setq attstr (getstring "\nNew attribute value: "))
           (vla-put-textstring (vlax-ename->vla-object (car att)) attstr)
           (ssadd (cdr (assoc 330 (entget (car att)))) ss1))
         (removereactor (vlr-reactors :vlr-command-reactor)))
        (T ())))

 

0 Likes
Message 9 of 11

john.uhden
Mentor
Mentor

I haven't played with reactors in years, but my simplistic view is to save whatever selection set you want to an AutoLisp variable.

 

F'rinstance, say some operation you perform selects entities (that are not being erased or exploded).

Then (setq SS (ssget "P")) to store the "Previous" selection into a 'PICKSET that you have named SS.

Then you do a bundle of things, reactors or otherwise.

Then you can reselect the saved selection set via (sssetfirst SS) or by (command "_.select" SS).

 

The only caution is if any of the items in the selection set has been eliminated or consumed, or if you are sloppy and try to maintain over 128 selection sets as AutoLisp variables (which AutoCAD won't allow you to do).  If you can, always try to keep PICKSET variables as local to a function so that they clean themselves up upon function completion.  Another method is to always give selection sets the same symbol name, though that can become overly restrictive to your overall programming needs.

 

I hope my idea is correct and helps you out.  Don't worry, 'cause if I'm wrong we will be advised by the usual wise guys 'n gals.

John F. Uhden

0 Likes
Message 10 of 11

msarqui
Collaborator
Collaborator

@Anonymous wrote:

Based on your level of effort evident in your response...


Well, maybe I learned from the master.

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/vla-saveas-with-dialog-box-prompt/m-p/6211788#M339660

 

Some people have skills, others just don't. And humbly I recognize that I can't understand reactors. That's why I came here and asked for help.
Some people have skills to program, others to socialize. Based on the respectful level of your response, I can say that your ability to program is very good.

0 Likes
Message 11 of 11

dbroad
Mentor
Mentor
Reactors are not always the best solution and they can cause problems if misused or not well written. Cancel, undo, and error situations are more complex. One should only resort to reactors if their programming skills are advanced and if they are willing to accept the lack of error reporting and AutoCad instability. I showed an alternative that met your need to preselected objects without using reactors. Using that approach is more suitable for beginning and intermediate customizes. Feel free to rewrite as needed. For you, in this application, building the selection set and then setting the pickset will work better with fewer problems.

If you are interested in reactors, I encourage you to prototype your callback functions with VLR-TRACE-REACTION. It reports argument values and will help you understand sequencing. Do this before writing your callbacks.
Architect, Registered NC, VA, SC, & GA.