#!/afs/ece/usr/tcl/bin/wish -f

set Bind_Keyword [file tail [info script]]
source "[file dirname [info script]]/../aux/frame.tcl"

# Help text.
set Help "" ; append Help {Edith -- Add keybindings for editing of textual widgets.

This program teaches widgets that contain text some simple commands to change
that text. It includes simple character insertion, deletion, cut and paste, plus
a few advanced features, such as unlimited undo, and region indenting.

} $TH_Bindings_Help {

Widgets of Edith

Maximum Undos Entry

The undo log can grow inordinately large during a long editing session. (Killing
the log can help alleviate this). This value is the maximum size that the undo
log can attain, when the undo log reaches this size, the oldest undos are
purged. When the default value of -1 is used, there is no limit.


Maximum Undo Label Size Scale

The command to show the last undoable command flashes a label in the widget's
frame containing the last undoable command. This command will often include a
sample of the text involved, and can be extremely long. This value specifies a
ceiling of how long this label should be; if the command is longer it gets
truncated to fit within the label.


'Add Modified Checkbutton' Checkbutton

This is a handy way of knowing when text has been modified. If this button is
set, edith will grace your widget with a checkbutton that normally stays off
until the text is modified, in which case it turns on. (It cannot be turned on
or off manually). If this button is off, then no checkbutton will be added.


'Teach Self_Insert to Canvases' Checkbutton

Generally text items that one can edit will contain some rudimentary bindings to
alter their contents, including one to insert text. Usually, if a text item has
such a binding, teaching it edith's text insertion routine will cause it to
insert each character twice, instead of once. So this button indicates whether
canvases should be taught edith's self-insert bindings (which support
overwriting and attempt to keep the insert cursor in view). If turned off, which
is the default, canvases do not receive th's self-insert bindings.


'Teach Newline to Entries' Checkbutton

Many entries (including the ones used by Teacher Hypertools) will have some
special binding for Return, usually that executes some command. In any case,
entries cannot display more than one line. So while teaching widgets to use
edith's insertion routines for <Return> is useful, it is generally not useful
for entries. So entries only learn edith's insertion routines for <Return> if
this button is on.

} $TH_Frame_Help {
The undo works individually for entry and text widgets, but it oversees all the
text entries on a canvas. This has some benefit, so it is a feature, not a bug

If you wish to apply class bindings, using the Shift key, be sure the input
focus is not on the 'Press Keys Here' label, or it will screw up your teaching
efforts. The best way to do this is to keep the mouse off the label, and put
the focus in the entry (which it starts off in, by default).

A canvas's text item can have bindings associated with one of its tags. These
bindings may interfere with Edith's bindings. For example, if both Edith and the
tag specify that a keypress inserts that key, the key will get inserted twice.
(Hence the self_insert button). Any other bindings the tag may define should not
be defined by edith (use the change checkbutton to change or delete them).

Edith cheerfully adds bindings and menu options to disabled widgets, without
regard to the fact that the widgets' contents won't get changed.
}


# Gives app all the code necessary to do our functions.
proc teach_code {app widget} {
  set class [send $app winfo class $widget]
  if {[widget_bindings $app $widget] != ""} {
    global TH_Dir Max_Undos Max_Undo_Label Modified_Button

    if {$class != "Text"} {
      include_files $app [list "browse.$class.tcl" "th_[set class]_goto"] \
	{browse.Misc.tcl th_string_wordstart}
    }

    include_files $app {edit.Misc.tcl th_look_undo}
    if {[file exists "$TH_Dir/lib/edit.[set class].tcl"]} {
      include_files $app [list edit.$class.tcl "th_[set class]_paste_selection"]
    }
    set cmd "set TH(Undo,Max,$class) $Max_Undos\nset TH(Undo,Label,Max) $Max_Undo_Label\n"

    if {![send $app "winfo exists .th_kill"]} {
      append cmd "text .th_kill\n"
    }
    do_cmd $app $cmd 0

    set f [teach_frame_code $app $widget]
    set fmb "$f.fmb"
    if {$Modified_Button && ![send $app winfo exists $fmb]} {
      do_cmd $app "checkbutton $fmb -relief raised -variable TH(Modified,$widget) -state disabled\npack $fmb -side right\n" 0
}}}

# For a widget, returns the appropriate bindings. (They will depend on the
# widget)
proc widget_bindings {app w} {
  global TH_Dir Bindings
  set class [send $app winfo class $w]
  if {[lsearch "Entry Text Canvas" $class] < 0} {return ""}
  set bindings ""

  set bindings [concat $bindings $Bindings(Edit,Misc)]

  if {[lsearch -exact [array names Bindings] "Edit,$class"] != -1} {
    set bindings [concat $bindings $Bindings(Edit,$class)]}

  global Canvas_Self Entry_Newline
  switch $class {
    "Entry" {set bindings [concat $bindings $Bindings(Edit,Self_Insert)]
      if $Entry_Newline {set bindings [concat $bindings $Bindings(Edit,Newline)]}
    } "Canvas" {if $Canvas_Self {
        set bindings [concat $bindings $Bindings(Edit,Newline) $Bindings(Edit,Self_Insert)]}
    } default {set bindings [concat $bindings $Bindings(Edit,Newline) $Bindings(Edit,Self_Insert)]}
  }

  return [widget_frame_bindings $bindings]
}


create_form_entry .max_undos "Maximum number of Undos Kept" Max_Undos -1
focus .max_undos.e
create_form_scale .max_undo_label "Maximum Size of Undo Label" Max_Undo_Label \
           30 -from 0 -to 70
frame .self ; pack .self -fill x
create_form_checkbutton .self.modified "Add Modified Checkbutton" \
           Modified_Button 0
create_form_checkbutton .self.key "Teach Self_Insert to Canvases" Canvas_Self \
           0 left
create_form_checkbutton .self.newline "Teach Newline to Entries" Entry_Newline \
           0 left


