Page 1 of 1

Calculating checkbox names ...

Posted: Thu Nov 01, 2007 4:18 pm
by cormullion
I can't get this code to work ...

Code: Select all

(load (string (env "NEWLISPDIR") "/guiserver.lsp"))

(gs:init) 
(gs:frame 'w1 200 200 200 200 "w1")
(gs:panel 'ControlPanel)
 
; options check boxes, defined in a list
(set 'check-boxes 
  '((TheCheckBox1 "one") 
    (TheCheckBox2 "two")
   ))

(dolist (cb check-boxes)
   (gs:check-box (first cb) 'checkboxing (last cb))
   (gs:set-selected (first cb) nil)
   (gs:add-to 'ControlPanel (first cb)))

(gs:add-to 'w1 'ControlPanel)

(gs:set-visible 'w1 true)

(define (checkboxing)
  (let ((widget (args 0))
        (value  (args 1))
        (option-number {})
       )
  (and 
    (find {MAIN:TheCheckBox} widget)
    (set 'option-number (last widget)) 
    (set (sym (string {option} option-number)) (if value 1 0)))
  
  (if (= (sym (string {option} option-number)) 1)
      (gs:set-selected (string {TheCheckBox} option-number) true)
      (gs:set-selected (string {TheCheckBox} option-number) nil))
  (println {option1: } option1 { option2: } option2)
  )
) 

(set 
 'option1 0 
 'option2 0 
)
Although the check boxes work ok, and set the variables that they're supposed to, there's an error message as well each time you click on them.

I'm trying to write code that handles a load of checkboxes - so constructing the checkbox name using (sym or (string should be the best way, but doesn't seem to work... Any thoughts?

Posted: Thu Nov 01, 2007 5:33 pm
by Lutz
you are thinking in the right direction, look at the following modified code which works (but the check disappears immediately, which is another logic error?):

Code: Select all

(load (string (env "NEWLISPDIR") "/guiserver.lsp")) 

(gs:init) 
(gs:frame 'w1 200 200 200 200 "w1") 
(gs:panel 'ControlPanel) 
  
; options check boxes, defined in a list 
(set 'check-boxes 
  '((TheCheckBox1 "one") 
    (TheCheckBox2 "two") 
   )) 

(dolist (cb check-boxes) 
   (gs:check-box (first cb) 'checkboxing (last cb)) 
   (gs:set-selected (first cb) nil) 
   (gs:add-to 'ControlPanel (first cb))) 

(gs:add-to 'w1 'ControlPanel) 

(gs:set-visible 'w1 true) 

(define (checkboxing) 
(println (args)) ;;;;;;;;;;;;;;;;;;;; added this for debugging
  (let ((widget (args 0)) 
        (value  (args 1)) 
        (option-number {}) 
       ) 
  (and 
    (find {MAIN:TheCheckBox} widget) 
    (set 'option-number (last widget)) 
    (set (sym (string {option} option-number)) (if value 1 0))) 
  
  (if (= (sym (string {option} option-number)) 1) 
      (gs:set-selected (string {MAIN:TheCheckBox} option-number) true) ;;; prepended MAIN 
      (gs:set-selected (string {MAIN:TheCheckBox} option-number) nil)) 
  (println {option1: } option1 { option2: } option2) 
  ) 
) 

(set 
 'option1 0 
 'option2 0 
)

(gs:listen) ;;;;;;; added this so clicks get processed
look for the 3 modifications prefixed with lots of ;;

Lutz

Posted: Thu Nov 01, 2007 9:26 pm
by cormullion
Thanks! I forgot "MAIN". (And I also forgot to evaluate the constructed symbol. Duh.)

This is the whole thing.

Code: Select all

(load (string (env "NEWLISPDIR") "/guiserver.lsp"))

(gs:init) 
(gs:frame 'RegexTester 200 200 650 650 "RegexTester")
(gs:panel 'MainPanel)
(gs:set-grid-layout 'MainPanel 2 2)

(gs:text-area 'string-input 'textfield-handler)
(gs:text-pane 'regex-input 'textfield-handler)
(gs:text-pane 'output 'gs:no-action)
 
(gs:set-background 'string-input '(0.9 0.9 0.8))
(gs:set-background 'regex-input '(0.9 0.7 0.7))
(gs:set-background 'output '(0.8 0.9 0.8))

(gs:set-font 'string-input "Sans Serif" 14)
(gs:set-font 'regex-input  "Sans Serif" 14)

(gs:panel 'ControlPanel)
(gs:set-grid-layout 'ControlPanel 13 1)

; The options checkboxes, defined in a list.
(set 'checkboxes 
  '((CheckBox1  {caseless}) 
    (CheckBox2  {multiline})
    (CheckBox3  {. matches all})
    (CheckBox4  {extended})
    (CheckBox5  {anchored})
    (CheckBox6  {$ matches at end of string, not before newline})
    (CheckBox7  {-})
    (CheckBox8  {first ch, not start of line ^ shouldn't match})
    (CheckBox9  {last char, not end of line $ shouldn't match})
    (CheckBox10 {invert greediness of quantifiers})
    (CheckBox11 {empty string considered invalid})
    (CheckBox12 {UTF8})))

; make the checkboxes
(dolist (cb checkboxes)
   (gs:check-box (first cb) 'checkboxing (last cb))
   (gs:set-selected (first cb) nil)
   (gs:add-to 'ControlPanel (first cb)))

(gs:add-to 'MainPanel 'string-input 'regex-input 'output 'ControlPanel)
(gs:add-to 'RegexTester 'MainPanel)
(gs:set-visible 'RegexTester true)

; checkbox handler
(define (checkboxing)
  (let ((widget (args 0))
        (value  (args 1))
        (option-number {})
       )
  (if (find {MAIN:CheckBox} widget)
    (begin
      (set 'option-number (replace {.*?(\d+)} widget $1 0)) 
      ; option-number should now be 1 2 3 4 5 to identify the checkbox... 
      (set (sym (string {option} option-number)) (if value 1 0))
      (if (= (eval (sym (string {option} option-number))) 1)
          (gs:set-selected (string {MAIN:CheckBox} option-number) true)
          (gs:set-selected (string {MAIN:CheckBox} option-number) nil))
      ; set the option global
      (set '*opt* 
        (+ (* 1 option1) 
           (* 2 option2) 
           (* 4 option3) 
           (* 8 option4) 
           (* 16 option5)
           (* 32 option6)
           (* 64 option7)
           (* 128 option8)
           (* 256 option9)
           (* 512 option10)
           (* 1024 option11)
           (* 2048 option12)
           ))))
  ; perform the regex again with the new options
  (do-match)
 )
) 

(define (do-match)
  (set 'results {})
  (set '$1 {} '$2 {} '$3 {} '$4 {} '$5 {} '$6 {} '$7 {} '$8 {} '$9 {})
  (if (catch (regex *rgx* *strng* *opt*) 'error)
      (begin
          (for (i 0 9) (push  (string {$} i { } (if ($ i) ($ i) {}) "\n") results -1))
          (gs:set-text 'output (string "Option: " *opt* "\n" results "\n" error))
          )
      (gs:set-text 'output (string {Problem: } error))))    
      
(define (textfield-handler id text)
	(gs:get-text id 'gettextcallback-handler))

(define (gettextcallback-handler id text)
  (and
    text
    (cond
       ((= id "MAIN:string-input")
          (set '*strng* (base64-dec text)))
       ((= id "MAIN:regex-input")
          (set '*rgx* (base64-dec text)))
       true
          (gs:no-action))
    (not (for-all empty? (list *rgx* *strng* *opt*)))
    (do-match *rgx* *strng* *opt*)
   )
)

(map set '(option1 option2 option3 option4 option5 option6 option7 option8 option9 option10 option11 option12) (dup 0 12))

(set 
 '*opt* 0 
 '*strng* {newLISP supports Perl-compatible regular expressions.} 
 '*rgx* "(n.{1,3}).*(rl-)")

; initial display
(gs:set-text 'string-input *strng*)
(gs:set-text 'regex-input *rgx*)
(do-match)

(gs:listen)

Posted: Thu Nov 01, 2007 10:05 pm
by Lutz
excellent! strong contender for this year's newLISP competition :-) (-> Norman ?)

Lutz


ps: what confused me at first was an error message displayed on wrong regex options, but then reading you code, I realized it was intended, the code is correctly catching the error and displaying it. Perhaps some additional text to calm down the panicking user :-?

Posted: Thu Nov 01, 2007 10:29 pm
by newdep
It sure is !!

very nicely done this one... aaaaaa great move ;-)

Posted: Thu Nov 01, 2007 10:55 pm
by cormullion
Lutz wrote: ps: what confused me at first was an error message displayed on wrong regex options, but then reading you code, I realized it was intended, the code is correctly catching the error and displaying it. Perhaps some additional text to calm down the panicking user :-?
:) Panicking user and confused coder!

I'm not 100% confident about catch yet.. I suppose I should have called 'error something else - it's only an error message if it's an error (and catch returns nil), otherwise it's the return value (and catch doesn't return nil)? Perhaps it should be 'status' or something...

By the way - those higher options (128?) ... are weird - do they all work?

Posted: Thu Nov 01, 2007 11:24 pm
by Lutz
By the way - those higher options (128?) ... are weird - do they all work?
The options (except for REPLACE_ONCE 0x8000) are passed directly on to the PCRE library routines (part of the newLISP code base and copy of the original PCRE code base) and I have reason to believe they work. I often use 512 for un-greediness, which works well, don't have experience with 128 and 256. This document gives you more insight and also has a few examples for using options: http://newlisp.org/downloads/pcrepattern.html

Lutz