Get string by text pick or user typing

James Maeding

Usenet Archive
Joined
Jul 7, 2003
Messages
331
Reaction score
0
Hello all,
I am in constant need of a function to get me a string value by two methods:
1) user picks text, mtext, attribute...
2) user types the value.

So the prompt would look like this:

Pick text or enter value:

The problem is that entsel does not allow arbitrary input (only keywords) and getstring will not let you pick an object. I was thinking of using grread somehow to capture a screen pick or characters typed. I could use a point picked to run a nentsel. Only drawback is the normal pickbox does not display, rather confusing for users. I am not interested in solutions that require a keyword to be typed to switch between the two modes, that is how I am doing it now... I am open to anything, maybe some arx function can do the trick... This must be a common need out there. thanks James Maeding Civil Engineer/Programmer
 
Here's an abridged excerpt from LABEL_IT. Just change the 0 to a 2 for a pickbox.

(while (and (not done)
(setq errobj (vl-catch-all-apply 'grread (list 1 14 0))) ) ;;(prompt something) (if (vl-catch-all-error-p errobj) (setq code '(2 27)) ; 'ESC (setq code errobj) ) (setq key (cadr code)) (cond ((or (= key 3)(= key 27)) (setq done 1 ans "Exit") ) ((= (car code) 3) ; 3=pick ;; ) ((= (car code) 5) ; 5=track ;; ) ((= (car code) 25) ; presumably a right click (in R14 it was 12) ;; ) ((listp key)(prin code)) ((or (= key 13) (= key 10) (= key 32)) (princ "\n") (setq ans (strcase ans) notprompt nil) (cond ((= ans "'_HELP") (repeat (strlen ans) (princ (chr 8)) (princ " ") (princ (chr 8)) ) (setq ans "") ;; ) ;; other conditions (1 (prompt "\nImproper response.") (setq ans "") ) ) ) ((and (= key 8)(> (strlen ans) 0)) ; backspace (setq ans (substr ans 1 (1- (strlen ans)))) (princ (chr 8)) (princ " ") (princ (chr 8)) ) ((and (> key 32) (< key 127)) (setq ans (strcat ans (princ (chr key)))) ) )
)

James Maeding said:
Hello all,
I am in constant need of a function to get me a string value by two methods:
1) user picks text, mtext, attribute...
2) user types the value.

So the prompt would look like this:

Pick text or enter value:

The problem is that entsel does not allow arbitrary input (only keywords) and
getstring will not let you pick an object.
I was thinking of using grread somehow to capture a screen pick or characters typed. I could use a point picked to run a nentsel. Only drawback is the normal pickbox does not display, rather confusing for users. I am not interested in solutions that require a keyword to be typed to switch
between the two modes, that is how I am
 
this is much better than the 'McMuffin! (see my earlier reply...)
thanks for sharing this John.

"John Uhden"
|>Here's an abridged excerpt from LABEL_IT. Just change the 0 to a 2 for a |>pickbox. |> |>(while (and (not done) |> (setq errobj (vl-catch-all-apply 'grread (list 1 14 0))) |> ) |> ;;(prompt something) |> (if (vl-catch-all-error-p errobj) |> (setq code '(2 27)) ; 'ESC |> (setq code errobj) |> ) |> (setq key (cadr code)) |> (cond |> ((or (= key 3)(= key 27)) |> (setq done 1 ans "Exit") |> ) |> ((= (car code) 3) ; 3=pick |> ;; |> ) |> ((= (car code) 5) ; 5=track |> ;; |> ) |> ((= (car code) 25) ; presumably a right click (in R14 it was 12) |> ;; |> ) |> ((listp key)(prin code)) |> ((or (= key 13) (= key 10) (= key 32)) |> (princ "\n") |> (setq ans (strcase ans) notprompt nil) |> (cond |> ((= ans "'_HELP") |> (repeat (strlen ans) |> (princ (chr 8)) (princ " ") (princ (chr 8)) |> ) |> (setq ans "") |> ;; |> ) |> ;; other conditions |> (1 (prompt "\nImproper response.") |> (setq ans "") |> ) |> ) |> ) |> ((and (= key 8)(> (strlen ans) 0)) ; backspace |> (setq ans (substr ans 1 (1- (strlen ans)))) |> (princ (chr 8)) (princ " ") (princ (chr 8)) |> ) |> ((and (> key 32) (< key 127)) |> (setq ans (strcat ans (princ (chr key)))) |> ) |> )
|>)

James Maeding
Civil Engineer/Programmer
 
John,
did you mean that
(vl-catch-all-apply 'grread (list 1 14 0)))
to be
(vl-catch-all-apply 'grread (list nil 14 0)))?

The 1 does not seem to allow any input, it just spits out a return as soon as the code is run. (I set done to nil before running) Seems like you would not miss that so an explanation would help me. This is handy stuff.
thanks

"John Uhden"
|>Here's an abridged excerpt from LABEL_IT. Just change the 0 to a 2 for a |>pickbox. |> |>(while (and (not done) |> (setq errobj (vl-catch-all-apply 'grread (list 1 14 0))) |> ) |> ;;(prompt something) |> (if (vl-catch-all-error-p errobj) |> (setq code '(2 27)) ; 'ESC |> (setq code errobj) |> ) |> (setq key (cadr code)) |> (cond |> ((or (= key 3)(= key 27)) |> (setq done 1 ans "Exit") |> ) |> ((= (car code) 3) ; 3=pick |> ;; |> ) |> ((= (car code) 5) ; 5=track |> ;; |> ) |> ((= (car code) 25) ; presumably a right click (in R14 it was 12) |> ;; |> ) |> ((listp key)(prin code)) |> ((or (= key 13) (= key 10) (= key 32)) |> (princ "\n") |> (setq ans (strcase ans) notprompt nil) |> (cond |> ((= ans "'_HELP") |> (repeat (strlen ans) |> (princ (chr 8)) (princ " ") (princ (chr 8)) |> ) |> (setq ans "") |> ;; |> ) |> ;; other conditions |> (1 (prompt "\nImproper response.") |> (setq ans "") |> ) |> ) |> ) |> ((and (= key 8)(> (strlen ans) 0)) ; backspace |> (setq ans (substr ans 1 (1- (strlen ans)))) |> (princ (chr 8)) (princ " ") (princ (chr 8)) |> ) |> ((and (> key 32) (< key 127)) |> (setq ans (strcat ans (princ (chr key)))) |> ) |> )
|>)

James Maeding
Civil Engineer/Programmer
 
John,
I can't get anything upon hitting a return or space bar but "Improper Response". Any idea what's wrong? Cute technique!
Aside: Debugging code where the ESC key is trapped, can get pretty dicey. ;-)

James,

I show an incomplete approach. A character typed should really trigger an edit dialog box where you can place the first character typed in case the user wants to backspace it out. Don't want to think that hard tonight. Once the choice (pick or type) has been made, grread is superfluous.

(defun c:test( / gr code data)
(setq gr (grread nil 4 2)) ;;allow escape to stop program. (setq code (car gr) data (cadr gr)) (cond ((= code 2) ;character <<--this should trigger a dialog box if not return or space (setq chr1 (chr data) str (getstring (strcat "\nString: " chr1) t) str (strcat chr1 str))) ((and (= code 3) ;pick (setq ss (SSGET DATA)) (setq ei (entget(ssname ss 0))) (member (CDR(ASSOC 0 EI)) '("TEXT" "MTEXT")) ) (CDR(ASSOC 1 EI))) (T (princ "\nNot a text string: "))))

Regards,
Doug
 
John, I guess I didnt understand the idea of tracking. I can imagine now that you could use it in a loop that does something with the coordinate like your edit pline routine does. That was my confusion...

I understand what the rest of the codes meant and I wasn't misunderstanding the 1 when you were just saying "not nil". Never hurts to read someone elses explanation though. By the way, I use 1 now instead of T just as you suggest due to your past threads.

I wanted to run command line prompt for getting the text so I wrote the following:
Note that I actually want a number so it uses a routine to extract a number from text...

(DEFUN GET-NUM-TXT-TYPE ( / ELEV ELEV-VAL ELEV-REST SRC-TEXT) (PRINC "\nPick text or enter elevation: ") (SETQ ELEV (vl-catch-all-apply 'grread '(NIL 14 2))) (COND ;ESC ((OR (vl-catch-all-error-p ELEV) (EQUAL ELEV '(2 13)) (EQUAL ELEV '(25 229)) ) (SETQ ELEV-VAL NIL) ) ;NUMBER ((AND (= (CAR ELEV) 2) (WCMATCH (CHR (CADR ELEV)) "1,2,3,4,5,6,7,8,9,0") ) ;THEN ASK FOR REST (SETQ ELEV-REST (vl-catch-all-apply '(lambda (GETREAL (STRCAT "\nPick text or enter elevation: " (CHR (CADR ELEV))))))) (IF (AND ELEV-REST (NOT (vl-catch-all-error-p ELEV-REST)) ) (SETQ ELEV-VAL (DISTOF (STRCAT (CHR (CADR ELEV)) (RTOS ELEV-REST 2 5)) 2)) ) ) ;IF ITS A POINT, SELECT TEXT ((AND (= (CAR ELEV) 3) (SETQ ELEV (NENTSELP (CADR ELEV))) ;(NENTSELP (GETPOINT)) (SETQ ELEV (CAR ELEV)) ) ;GET TEXT VALUE AND TEST FOR NUMBER (IF (OR (= (cdr (assoc 0 (entget ELEV))) "ATTRIB") (= (cdr (assoc 0 (entget ELEV))) "TEXT") (= (cdr (assoc 0 (entget ELEV))) "MTEXT") ) (PROGN (SETQ SRC-TEXT (CDR (ASSOC 1 (ENTGET ELEV)))) ;CLEAN OUT MTEXT FORMATS IF MTEXT (IF (AND (= (CDR (ASSOC 0 (ENTGET ELEV))) "MTEXT") (WCMATCH SRC-TEXT "*;*") ) (SETQ SRC-TEXT (SUBSTR SRC-TEXT (+ 1 (VL-STRING-SEARCH ";" SRC-TEXT)))) ) ;EXTRACT NUMBER (SETQ ELEV-VAL (DISTOF SRC-TEXT 2)) ) ) ) ) ELEV-VAL )

I actually do some cleaning of SRC-TEXT before doing the distof but I removed that for simplicity. Ok guys, send the comments, I'm sure its not perfect... I wrote it befor reading the replies to my last post so forgive me if it looks like I am stealing ideas, the fact is I am and so I post the result so others can use it. (honor among thieves?) I must say though that I am so stoked we got this far. The extra thought to slick stuff out is so worth it. I don't think I would have pursued it if your replies hadnt been posted.

James Maeding
|>Hello all,
|>I am in constant need of a function to get me a string value by two methods:
|>1) user picks text, mtext, attribute...
|>2) user types the value.
|>
|>So the prompt would look like this:
|>
|>Pick text or enter value:
|>
|>The problem is that entsel does not allow arbitrary input (only keywords) and getstring will not let you pick an object. |>I was thinking of using grread somehow to capture a screen pick or characters typed. |>I could use a point picked to run a nentsel. |>Only drawback is the normal pickbox does not display, rather confusing for users. |>I am not interested in solutions that require a keyword to be typed to switch between the two modes, that is how I am |>doing it now... |>I am open to anything, maybe some arx function can do the trick... |>This must be a common need out there. |>thanks |>James Maeding |>Civil Engineer/Programmer

James Maeding
Civil Engineer/Programmer
 

Latest threads

Back
Top