Jump to content

help with a DCL retrieving values


BIGAL

Recommended Posts

I decide to write my own version of a multiline input dcl to suit our needs, the idea being that the size of the dcl is based on the number of items in a list, so that part works great I end up with a multiline dcl with default values. I had it working and had a couple of funny things happening so changed the code now I have lost the whole thing from working.

 

The repeat for setting the tile default value that works but the tile is not returning the value

 

Any help would be appreciated.

 

; Input  Dialog box with variable title
; multiple lines of dcl input supported
; add extra values to the list
(vl-load-com)

; returns the value of key1 key2 and key3 etc  as strings

; sample code (ah:getval2018 "heading at top" (list "Line 1" 5 4 "1" "Line2" 8 7 "2"))
; (setq dcllst (list "Line 1" 5 4 "1" "Line2" 8 7 "22" "Line3" 8 7 "3" "Line4" 8 7 "44"))
; (AH:getval2018 "This is heading" (list "Line 1" 5 4 "1" "Line2" 8 7 "22" "Line3" 8 7 "3" "Line4" 8 7 "44"))
(defun  AH:getval2018 (heading dcllst /  x y ans fo fname keynum)
(setq num (/ (length dcllst) 4))
(setq x 0)
(setq  y 0)
(setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w"))
(write-line "ddgetvalAH : dialog {" fo)
(write-line  (strcat "	label =" (chr 34) heading (chr 34) " ;" )fo)
(write-line " : column {" fo)
(repeat num
(write-line "spacer_1 ;" fo)
(write-line ": edit_box {" fo)
(setq keynum (strcat "key" (rtos (setq y (+ Y 1)) 2 0)))
(write-line (strcat "    key = " (chr 34) keynum (chr 34) ";") fo)
(write-line  (strcat " label = "  (chr 34) (nth x dcllst) (chr 34) ";" ) fo)
(write-line (strcat "     edit_width = " (rtos (nth (+ x 1) dcllst) 2 0) ";" ) fo)
(write-line (strcat "     edit_limit = " (rtos (nth (+ x 2) dcllst) 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(setq x (+ x 4))
)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line "ok_only;}" fo)
(close fo)
(setq dcl_id (load_dialog  fname))
(if (not (new_dialog "ddgetvalAH" dcl_id))
(exit))
(setq x -1)
(setq y 0)
(repeat  num
(setq keynum  (strcat "key" (rtos (setq y (+ Y 1)) 2 0)))
(setq valnum (strcat "val" (rtos y 2 0)))
(set_tile keynum (nth (setq x (+ x 4)) dcllst))
;;;; problem is here
(action_tile keynum (strcat "(set " "(read valnum)" " $value)"))
(mode_tile  keynum  3)
 )
(start_dialog)
(unload_dialog dcl_id)
)
(AH:getval2018 "This is heading" (list "Line 1" 5 4 "1" "Line2" 8 7 "22" "Line3" 8 7 "3" "Line4" 8 7 "44"))

 

Link to comment
Share on other sites

Perhaps something like this, not quite sure - it returns !val1 !val2 !val3 ...

 

; sample code (ah:getval2018 "heading at top" (list "Line 1" 5 4 "1" "Line2" 8 7 "2"))
; (setq dcllst (list "Line 1" 5 4 "1" "Line2" 8 7 "22" "Line3" 8 7 "3" "Line4" 8 7 "44"))
; (AH:getval2018 "This is heading" (list "Line 1" 5 4 "1" "Line2" 8 7 "22" "Line3" 8 7 "3" "Line4" 8 7 "44"))
(defun AH:getval2018 ( heading dcllst / x y fo fname keynum valnum keylst vallst )
  (setq num (/ (length dcllst) 4))
  (setq x 0)
  (setq y 0)
  (setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w"))
  (write-line "ddgetvalAH : dialog {" fo)
  (write-line (strcat "	label =" (chr 34) heading (chr 34) " ;" ) fo)
  (write-line " : column {" fo)
  (repeat num
    (write-line "spacer_1 ;" fo)
    (write-line ": edit_box {" fo)
    (setq keynum (strcat "key" (rtos (setq y (1+ y)) 2 0)))
    (write-line (strcat "    key = " (chr 34) keynum (chr 34) ";") fo)
    (write-line (strcat "  label = " (chr 34) (nth x dcllst) (chr 34) ";") fo)
    (write-line (strcat "     edit_width = " (rtos (nth (+ x 1) dcllst) 2 0) ";") fo)
    (write-line (strcat "     edit_limit = " (rtos (nth (+ x 2) dcllst) 2 0) ";") fo)
    (write-line "   is_enabled = true ;" fo)
    (write-line "    }" fo)
    (setq x (+ x 4))
  )
  (write-line "    }" fo)
  (write-line "spacer_1 ;" fo)
  (write-line "ok_only;}" fo)
  (close fo)
  (setq dcl_id (load_dialog fname))
  (if (not (new_dialog "ddgetvalAH" dcl_id))
    (exit)
  )
  (setq x -1)
  (setq y 0)
  (repeat num
    (setq keynum (strcat "key" (rtos (setq y (1+ y)) 2 0)))
    (setq valnum (strcat "val" (rtos y 2 0)))
    (setq keylst (cons keynum keylst))
    (setq vallst (cons valnum vallst))
  )
  (foreach a (reverse vallst)
    (set (read a) (nth (setq x (+ x 4)) dcllst))
  )
  (setq x -1)
  (foreach ab (mapcar '(lambda ( a b ) (list a b)) (reverse keylst) (reverse vallst))
    (set_tile (car ab) (nth (setq x (+ x 4)) dcllst))
    (action_tile (car ab) (strcat "(setq " (cadr ab) " $value)"))
    (mode_tile (car ab) 3)
  )
  (start_dialog)
  (unload_dialog dcl_id)
  (vl-file-delete fname)
)

HTH., M.R.

  • Like 1
Link to comment
Share on other sites

The problem is the (read valnum). You are setting it inside a loop, but the action tile action takes place outside the loop when valnum = val4 so every action tile is setting val4.

Link to comment
Share on other sites

12 minutes ago, dlanorh said:

The problem is the (read valnum). You are setting it inside a loop, but the action tile action takes place outside the loop when valnum = val4 so every action tile is setting val4.

 

action tile is inside loop, the problem was actually (set) function... In my example I used (setq) and avoided (read) by directly (strcat) - ing string value...

Link to comment
Share on other sites

17 minutes ago, marko_ribar said:

 

action tile is inside loop, the problem was actually (set) function... In my example I used (setq) and avoided (read) by directly (strcat) - ing string value...

 

Sorry, didn't see your post until I had posted. Yes, in BigAls code, setting the action tile is inside the loop, but the loop finishes. At this point valnum = val4. The dialog then starts and the action tile event takes place outside the loop (set (read valnum) $value) for each action tile event; and outside the loop valnum = val4. So every action tile event sets val4.

 

Nice workaround by the way.

Edited by dlanorh
Link to comment
Share on other sites

just 4 fun :

 

;
; for BigAl - rlx 4 sep 2018


(defun Eddie ( $txt1 %lst / err fn fp dcl nof-eddies Eddie-list slider-index org-list)
  (Eddie_Init)
  (Eddie_Dialog)
  (Eddie_Exit)
  (terpri)
  %lst
)

(defun Eddie_Init ()
  (setq err *error* *error* Eddie_err org-list %lst)
  (cond
    ((not (setq fn (vl-filename-mktemp "Eddie.dcl"))))
    ((not (setq fp (open  fn "w"))))
    ((null %lst))
    (t (setq nof-eddies (length %lst)))
  )
   
  (if (null %lst)
    (progn (alert "Nothing to show")(Eddie_Exit))
    (progn
      (Eddie_write_header)
      (if (<= nof-eddies 10)(Eddie_write_body1 %lst)(Eddie_write_body2 %lst))
      (Eddie_write_footer)
    )
  )
  (if fp (close fp))(gc)
  (setq slider-index 0)
)

(defun Eddie_err (s) (princ s)(Eddie_Exit)(princ))
(defun Eddie_Exit ()
  (setq *error* err)
  (if fp (close fp))
  (if dcl (unload_dialog dcl))
  (if (and fn (findfile fn))(vl-file-delete fn))
)


(defun Eddie_write_header ()
  (write-line
    (strcat
      "Eddie:dialog{label=\"Eddie - BigAl (2018)\";spacer;spacer;"
      ":text_part {key=\"txt1\";width=32;fixed_width=true;}"
      ) fp))


(defun Eddie_write_body1 ( %lst / i )
  (write-line ":boxed_row {" fp)
  (write-line ":column {" fp)
  (setq i 0)
  (mapcar
    '(lambda (x)
       (write-line
         (strcat ":text_part{key=\"tp" (itoa i) "\";label=\"" (car x) "\";width=32;fixed_width=true;}")
         fp
       )
       (setq i (1+ i))
     )
    %lst
  );|close column|;(write-line "spacer;}" fp)
 
  (write-line ":column {" fp)
  (setq i 0)
  (mapcar
    '(lambda (x)
       (write-line
         (strcat ":edit_box{key=\"eb" (itoa i) "\";width=12;fixed_width=true;}")
         fp
       )
       (setq i (1+ i))
     )
    %lst
  );|close column & row|;(write-line "spacer;}}" fp)
)

(defun Eddie_write_body2 ( %lst / i )
  (write-line ":boxed_row {" fp)
  (write-line ":column {" fp)
  (setq i 0)
  (repeat 10
    (write-line
      (strcat ":text_part {key=\"tp" (itoa i) "\";label=\"" (car (nth i %lst)) "\";width=32;fixed_width=true;}")
      fp
    )
    (setq i (1+ i))
  ) ;|close column|; (write-line "spacer;}" fp)

  (write-line ":column {" fp)
  (setq i 0)
  (repeat 10
    (write-line
      (strcat ":edit_box {key=\"eb" (itoa i) "\";width=12;fixed_width=true;}")
      fp
    )
    (setq i (1+ i))
  );|close column|; (write-line "spacer;}" fp)
 
  (write-line
    (strcat ":column {:slider {key=\"sldr\";layout=vertical;min_value="
            (itoa (- 0 nof-eddies)) ";max_value=0;small_increment=1;big_increment=10;value=0;}}}"
    )
    fp
  )
)

(defun Eddie_write_footer ()
  (write-line "spacer;spacer;ok_cancel;}" fp))

(defun Eddie_Dialog ( / n drv inp)
  (if (and (setq n 0 dcl (load_dialog fn)) (new_dialog "Eddie" dcl))
    (progn
      (Eddie_DialogUpdate)
      (Eddie_DialogActions)
      (setq drv (start_dialog))
      (if (= drv 1)
 (mapcar '(lambda (x y) (if (= x "1")(setq return (cons y return)))) Eddie-list %lst)
 (setq return nil))
    )
  )
)

(defun Eddie_DialogUpdate ( / i )
  (if (= (type $txt1) 'STR)(set_tile "txt1" $txt1))
  (set_tile "sldr" (itoa slider-index))
  (update_Eddies)
)

(defun Eddie_DialogActions ()
  (repeat 10 (action_tile (strcat "eb" (itoa n)) (strcat "(edit_me $value " (itoa n) ")" ))(setq n (1+ n)))
  (action_tile "sldr" "(update_slider $value)")
  (action_tile "ok" "(done_dialog 1)")
  (action_tile "cancel" "(setq %lst org-list)(done_dialog 0)")
)

(defun update_slider ( #i )
  (setq slider-index (atoi #i))
  (Eddie_DialogUpdate)
)

(defun update_Eddies (/ Eddie-index Eddie-name i)
  ;max number of Eddies in dialog is 10
  (if (> (abs slider-index) (- nof-eddies 10))
    (setq Eddie-index (- nof-eddies 10))(setq Eddie-index (abs slider-index)))
  (if (< Eddie-index 0)(setq Eddie-index 0))
  (setq i 0)
  (while (and (< i 10) (setq Eddie-name (car (nth Eddie-index %lst))))
    (set_tile (strcat "tp" (itoa i)) Eddie-name)
    (set_tile (strcat "eb" (itoa i)) (vl-princ-to-string (cadr (nth Eddie-index %lst))))
    (setq i (1+ i) Eddie-index (1+ Eddie-index))
  )
)

(defun edit_me ( $v #i / idx )
  (if (> (abs slider-index) (- nof-eddies 10))
    (setq idx (- nof-eddies 10))  (setq idx (abs slider-index)))
  (setq idx (+ #i (if (< idx 0) 0 idx))
        %lst (subst (list (car (nth idx %lst)) $v) (nth idx %lst) %lst)))

;print list (test function)
(defun prl (lst)(mapcar '(lambda(x)(princ "\n")(princ x)) lst))


(defun c:t1 ()
  (prl
    (Eddie "This is heading" '(("Line 1" 1) ("Line 2" 22) ("Line 3" 33)("Line 4" 44)))
  )
  (princ)
)

(defun c:t2 ()
  (prl
    (Eddie "This is heading"
         '( ("Line  1"  11) ("Line  2"  22) ("Line  3"  33) ("Line  4"  44) ("Line  5"  55)
            ("Line  6"  66) ("Line  7"  77) ("Line  8"  88) ("Line  9"  99) ("Line 10" 100)
            ("Line 11" 110) ("Line 12" 120) ("Line 13" 130) ("Line 14" 140) ("Line 15" 150)
          )
    )
  )
  (princ)
)

Edited by rlx
oh yeah , forgot cancel - fixed
  • Funny 1
Link to comment
Share on other sites

My 2 cents :

 

Change

 

(action_tile keynum (strcat "(set " "(read valnum)" " $value)"))

To

 

(action_tile keynum (strcat "(setq val" (itoa y) " $value)"))

 

and remove

 

(setq valnum (strcat "val" (rtos y 2 0)))

 

Link to comment
Share on other sites

@dlanorh

You are right, but I think that this is not only issue... After looping and completion of action-tile (s), unchanged values don't appear to be signed to val(s) variables... So I had to do it the way I modified it... Not sure, but check if you want that by just pressing OK at dialog box and do not change anything... If val(s) aren't nil(s) then your fix is OK, but if I am right then I suppose it had to be coded bigger... And I still can't quite understand why (set) won't work - has to be (setq) - ing...

Link to comment
Share on other sites

25 minutes ago, marko_ribar said:

@dlanorh

You are right, but I think that this is not only issue... After looping and completion of action-tile (s), unchanged values don't appear to be signed to val(s) variables... So I had to do it the way I modified it... Not sure, but check if you want that by just pressing OK at dialog box and do not change anything... If val(s) aren't nil(s) then your fix is OK, but if I am right then I suppose it had to be coded bigger... And I still can't quite understand why (set) won't work - has to be (setq) - ing...

@marko_ribar

I added some code to BigAl's to handle the OK being selected, and collect the values into a list to pass back to the calling program. This returns the expected values. My adapted code :

 

(defun  AH:getval2018 (heading dcllst /  x y ans fo fname keynum)
(setq num (/ (length dcllst) 4))
(setq x 0)
(setq  y 0)
(setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w"))
(write-line "ddgetvalAH : dialog {" fo)
(write-line  (strcat "	label =" (chr 34) heading (chr 34) " ;" )fo)
(write-line " : column {" fo)
(repeat num
(write-line "spacer_1 ;" fo)
(write-line ": edit_box {" fo)
(setq keynum (strcat "key" (rtos (setq y (+ Y 1)) 2 0)))
(write-line (strcat "    key = " (chr 34) keynum (chr 34) ";") fo)
(write-line  (strcat " label = "  (chr 34) (nth x dcllst) (chr 34) ";" ) fo)
(write-line (strcat "     edit_width = " (rtos (nth (+ x 1) dcllst) 2 0) ";" ) fo)
(write-line (strcat "     edit_limit = " (rtos (nth (+ x 2) dcllst) 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(setq x (+ x 4))
)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line "ok_only;}" fo)
(close fo)
(setq dcl_id (load_dialog  fname))
(if (not (new_dialog "ddgetvalAH" dcl_id))
(exit))
(setq x -1)
(setq y 0)
(repeat  num
(setq keynum  (strcat "key" (rtos (setq y (+ Y 1)) 2 0)))
(set_tile keynum (nth (setq x (+ x 4)) dcllst))
;;;; problem is here
(action_tile keynum (strcat "(setq val" (itoa y) " $value)"))
(mode_tile  keynum  3)
 )
(action_tile "accept" "(done_dialog 1)")
(setq x_val (start_dialog))
(if (= x_val 1) (setq ans (list val1 val2 val3 val4)))
(unload_dialog dcl_id)
(setq rtn ans)
)
(setq a (AH:getval2018 "This is heading" (list "Line 1" 5 4 "1" "Line2" 8 7 "22" "Line3" 8 7 "3" "Line4" 8 7 "44")))

Funnily (set (read numval) 1) works on the commandline but errors when you try to (strcat "set " (read numval) " $value)")

 

The error was solved by changing (read numval) to "(read numval)". This however is a string and so (read numval) is never evaluated in the strcat which produces the string "set (read numval) $value)". This string is set as the action command for all 4 edit boxes, it is only evaluated when the action_tile  event is fired, which is outside the loop. Hope that makes sense.

Link to comment
Share on other sites


(defun tst1 ( / $value val1)
  ; (action_tile "key1" (strcat "(setq " "val1" " $value)"))
  ; -> (action_tile "key1" "(setq val1 $value)")
  (setq $value "1")
  (eval "(setq val1 $value)")
  (eval (read "(setq val1 $value)"))
  (princ)
)

(defun tst2 ( / $value val1)
  ; (action_tile "key1" (strcat "(set " "val1" " $value)"))
  ; -> (action_tile "key1" "(set val1 $value)")
  (setq $value "1")
  (eval "(set val1 $value)")
  ; (eval (read "(set val1 $value)")) ; error: bad argument type: symbolp "1"
  (eval (read "(set (quote val1) $value)"))
  (princ)
)

Link to comment
Share on other sites

@dlanorh

 

By typing :

(setq ans (list val1 val2 val3 val4))

you are missing the whole purpose of BigAl's sub function... It was meant to be applicable to any length of list provided to sub function... So val50 is theoretically possible, and you reacted only on list BigAl provided as an example, not explicit must...

Link to comment
Share on other sites

1 hour ago, marko_ribar said:

@dlanorh

 

By typing :


(setq ans (list val1 val2 val3 val4))

you are missing the whole purpose of BigAl's sub function... It was meant to be applicable to any length of list provided to sub function... So val50 is theoretically possible, and you reacted only on list BigAl provided as an example, not explicit must...

 

@marko_ribar

You misunderstand. The code additions were  just to show how I confirmed the DCL output, by returning the data as a list. :)

Link to comment
Share on other sites

Thank for answering

 

I am pretty sure this is where I got to (action_tile keynum (strcat "(setq val" (itoa y) " $value)")) and as pointed out unless you click a box it does not return a default value, the interesting part though is if you write the action_tile in multiple lines as hardcoded it will return the default values pressing ok only.  Will look into the (if (= x_val 1) (setq ans (list val1 val2 val3 val4))) but as a cons which can can be made to loop for the number of entries. 

 

Will post again once I have a play.
 

Link to comment
Share on other sites

If you abandon action tiles for each edit box and trying to construct and set variables, you can collect all the tile values in a list before issuing (done dialog) in the "accept" (OK) action tile.

 

(repeat num
  (setq keynum  (strcat "key" (rtos (setq y (+ Y 1)) 2 0))
        key_lst (cons keynum key_lst);construct a list of keys
  );end_setq     
  (set_tile keynum (nth (setq x (+ x 4)) dcllst))
  (mode_tile keynum 3)
)
(action_tile "accept" "(mapcar '(lambda (x) (setq v_lst (cons (get_tile x) v_lst))) key_lst)(done_dialog)")
(unload_dialog dcl_id)
(setq rtn v_lst); this is needed here if you want to return the list otherwise it returns nil from the (unload_dialog)

This returns the list of values from all the edit boxes in the order (edit box key1) -> (edit box key(n))

Link to comment
Share on other sites

Dlanort did you try the code all it did was lock up my autocad could not exit the dcl tried "ok" as well.

 

Its so frustrating had it all working and changed then lost the solution.

 

Link to comment
Share on other sites

37 minutes ago, BIGAL said:

Dlanort did you try the code all it did was lock up my autocad could not exit the dcl tried "ok" as well.

 

Its so frustrating had it all working and changed then lost the solution.

 

 

Yep, tested it in my version 2012, but I can see from my snippet its missing a line (start dialog). My apologies, I don't know how it got deleted.

 

It should be

 

(repeat  num
(setq keynum  (strcat "key" (rtos (setq y (+ Y 1)) 2 0))
      key_lst (cons keynum key_lst)
)     
(set_tile keynum (nth (setq x (+ x 4)) dcllst))
(mode_tile  keynum  3)
 )
(action_tile "accept" "(mapcar '(lambda (x) (setq v_lst (cons (get_tile x) v_lst))) key_lst)(done_dialog)")
(start_dialog)
(unload_dialog dcl_id)
(setq rtn v_lst)

 

Edited by dlanorh
Link to comment
Share on other sites

If it helps, this is the complete code i used. At the end is the defun used to test it.

 

(vl-load-com)

(defun  AH:getval2018 (heading dcllst /  x y ans fo fname keynum key_lst v_lst)
(setq num (/ (length dcllst) 4))
(setq x 0)
(setq  y 0)
(setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w"))
(write-line "ddgetvalAH : dialog {" fo)
(write-line  (strcat "	label =" (chr 34) heading (chr 34) " ;" )fo)
(write-line " : column {" fo)
(repeat num
(write-line "spacer_1 ;" fo)
(write-line ": edit_box {" fo)
(setq keynum (strcat "key" (rtos (setq y (+ Y 1)) 2 0)))
(write-line (strcat "    key = " (chr 34) keynum (chr 34) ";") fo)
(write-line  (strcat " label = "  (chr 34) (nth x dcllst) (chr 34) ";" ) fo)
(write-line (strcat "     edit_width = " (rtos (nth (+ x 1) dcllst) 2 0) ";" ) fo)
(write-line (strcat "     edit_limit = " (rtos (nth (+ x 2) dcllst) 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(setq x (+ x 4))
)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line "ok_only;}" fo)
(close fo)
(setq dcl_id (load_dialog  fname))
(if (not (new_dialog "ddgetvalAH" dcl_id))
(exit))
(setq x -1)
(setq y 0)
(repeat  num
(setq keynum  (strcat "key" (rtos (setq y (+ Y 1)) 2 0))
      key_lst (cons keynum key_lst)
)     
(set_tile keynum (nth (setq x (+ x 4)) dcllst))
(mode_tile  keynum  3)
 )
(action_tile "accept" "(mapcar '(lambda (x) (setq v_lst (cons (get_tile x) v_lst))) key_lst)(done_dialog)")
(start_dialog)
(unload_dialog dcl_id)
(setq rtn v_lst)
)

(defun c:test ( / a) (setq a (AH:getval2018 "This is heading" (list "Line 1" 5 4 "1" "Line2" 8 7 "22" "Line3" 8 7 "3" "Line4" 8 7 "44")))(princ a))

 

Edited by dlanorh
Link to comment
Share on other sites

Thanks dlanorh the code works, I removed the V_lst from the local variables this allows passing to another program as a global variable, still not 100% similar problem to when I screwed up my code if ran multiple times it does not overwrite the v_lst tried a couple of things, will play  a bit more unfortunately I am time poor at the moment may make the V_lst part a non lambda function etc.

 

Ok fixed removed V_lst from variable definition, added (setq v_lst '()) at start so resets each time its run.

 

Here is a working example the dcl and a simple 3d furniture table generator.

Make furniture table.lsp

GETVALSdcl2.lsp

Edited by BIGAL
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...