TkwidgetText

Moderator: GiD Team

Post Reply
BLMichielsen
Posts: 2
Joined: Fri Aug 25, 2017 9:01 am

TkwidgetText

Post by BLMichielsen »

Dear forum,

I am using GiD 13.0.2 and put a TkwidgetText in a customised ProblemType.prb file like this

Code: Select all

TITLE: Scenario
QUESTION: Python_script:
VALUE: import Module
TKWIDGET: GidUtils::TkwidgetText
This correctly provides an editable text window. I can complete the text with mutiple lines.
If I click the accept button and then save the project, the project.prb file has a VALUE with
the text I entered. But at a subsequent restart of GiD on the same project I get an error
because, apparently, GiD does not read multi-line VALUE: fields.

I could wrap the Text widget in another one which takes care that the VALUE is actually the
name of a file which is read and written. However, as the comment in dev_kit.tcl suggests

Code: Select all

#to be used by TKWIDGET to use a text widget instead of an entry
#e.g.
#QUESTION: your_question
#VALUE: 
#TKWIDGET: GidUtils::TkwidgetText
I was expecting that it would work as is.

Thank you in advance for any advice,

Bas Michielsen
User avatar
escolano
Posts: 1918
Joined: Sun Sep 05, 1982 10:51 pm

Re: TkwidgetText

Post by escolano »

You are right,
The problem is that the 'question' where the 'text content' is tricky stored must be a single line of text, it was not designed for multiple lines.
and saving/reading to disk multi-lines are unexpected

A possible extra trick is to codify the multi-line text as base-64, and decodify again to be showed to the final user.
In dev_kit.tcl the proc GidUtils::TkwidgetText must be modified in this way
and to print the question value in the .bas file must be also decoded like this
*tcl(encrypter BASE64 decode *gendata(Python_script))

Code: Select all

#to be used by TKWIDGET to use a text widget instead of an entry
#e.g.
#QUESTION: your_question
#VALUE: 
#TKWIDGET: GidUtils::TkwidgetText
#
#store the text encoded as base64 to be saved/read to/from disk allowing multiple lines (not allowed in normal question data)
#to print the value for the calculation data must be decoded again!!
#instead of use *gendata(your_question) must do something like *tcl(encrypter BASE64 decode *gendata(your_question))
proc GidUtils::TkwidgetText { event args } {
    global tkwidgedprivtext
    switch $event {
        INIT {            
            lassign $args PARENT current_row_variable GDN STRUCT QUESTION    
            upvar $current_row_variable ROW      
            #initialize variable to current field value	    
            set value [encrypter BASE64 decode [DWLocalGetValue $GDN $STRUCT $QUESTION]]
            set entry ""
            foreach item [grid slaves $PARENT -row [expr $ROW-1]] {
                if { [winfo class $item] == "Entry"  || [winfo class $item] == "TEntry" } {
                    #assumed that it is the only entry of this row
                    set entry $item
                    break
                }
            }
            #trick to fill in the values pressing transfer from an applied condition
            if { [lindex [info level 2] 0] == "DWUpdateConds" } {
                set values [lrange [lindex [info level 2] 2] 3 end]
                set index_field [LabelField $GDN $STRUCT $QUESTION]
                set value [lindex $values $index_field-1]                                     
            }
            set w [tk::text $PARENT.ctext$QUESTION]
            $w insert end $value
            set tkwidgedprivtext($QUESTION,widget) $w            
            grid $tkwidgedprivtext($QUESTION,widget) -row [expr $ROW-1] -column 1 -sticky ew -columnspan 2
            if { $entry != "" } {
                grid remove $entry
            } else {
                #assumed that entry is hidden
                grid remove $tkwidgedprivtext($QUESTION,widget)
            }
        }
        SYNC {
            lassign $args GDN STRUCT QUESTION       
            if { [info exists tkwidgedprivtext($QUESTION,widget)] && [winfo exists $tkwidgedprivtext($QUESTION,widget)] } {                                 
                set value [$tkwidgedprivtext($QUESTION,widget) get 1.0 end]
                DWLocalSetValue $GDN $STRUCT $QUESTION [encrypter BASE64 encode $value]
            }
        }
        DEPEND {
            lassign $args GDN STRUCT QUESTION ACTION VALUE           
            if { [info exists tkwidgedprivtext($QUESTION,widget)] && [winfo exists $tkwidgedprivtext($QUESTION,widget)] } {
                if { $ACTION == "HIDE" } {
                    grid remove $tkwidgedprivtext($QUESTION,widget)
                } else {
                    #RESTORE
                    grid $tkwidgedprivtext($QUESTION,widget)
                }
            } else {
 
            }
        }
        CLOSE {
            array unset tkwidgedprivtext
        }
        default {
            return [list ERROR [_ "Unexpected tkwidget event"]]
        }
    }
    #a tkwidget procedure must return "" if Ok or [list ERROR $description] or [list WARNING $description] 
    return ""
}
User avatar
escolano
Posts: 1918
Joined: Sun Sep 05, 1982 10:51 pm

Re: TkwidgetText

Post by escolano »

The trick of encoding the question value as a base64 string (an ASCII string without spaces) works well, but there is small detail:
when opening and closing the data window always ask "Data has changed. Do you want to save it?", also if the user has not changed the text, because GiD is comparing the current decoded text with the inner copy of the encoded question value.
It is not a big problem. If the user select save the same value must be saved again.
BLMichielsen
Posts: 2
Joined: Fri Aug 25, 2017 9:01 am

Re: TkwidgetText

Post by BLMichielsen »

Thank you very much for your suggestions !

Bas
Post Reply