#!/afs/ece/usr/tcl/bin/wish -f
# The next line is executed by most shells, but not Tcl \
wish $0 $*


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

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 can't be changed.

Cutting a large region of text line by line only works from the keyboard. The
menu option will clear the clipboard every time it is called.}


# Gives app all the code necessary to do our functions.
proc teach_code {} {
  global Class App Widget TH_Dir Max_Undos Max_Undo_Label Modified_Button
  if {[lsearch "Entry Text Canvas" $Class] < 0} {return ""}

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

  include_files {edit.Misc.tcl th_look_undo}
  if {[file exists "$TH_Dir/lib/edit.[set Class].tcl"]} {
    include_files [list edit.$Class.tcl "th_[set Class]_undo"]
  }
  do_cmd_set TH(Undo,Max,$Class) $Max_Undos
  do_cmd_set TH(Undo,Label,Max) $Max_Undo_Label

  if {[lsearch "Canvas Text" $Class] >= 0} {
    teach_binding_code Kill_Line
  }

  set fmb "[teach_frame_code].fmb"
  if {$Modified_Button && ![send $App winfo exists $fmb]} {
    do_cmd_set TH(Modified,$Widget) 0
    do_cmd "pack \[checkbutton $fmb -relief flat -variable TH(Modified_Button,$Widget) -offvalue {} -onvalue {Modified} -indicatoron 0 -textvariable TH(Modified_Button,$Widget) -command \{if \{\$TH(Modified_Button,$Widget) == \"\"\} \{set TH(Modified,$Widget) 0\} else \{set TH(Modified,$Widget) 1\}\}\] -side left\n" 0
    do_cmd "trace variable TH(Modified,$Widget) w \{th_modified_widget $Widget $fmb\}\n" 0
}}

# For a widget, returns the appropriate bindings. (They will depend on the
# widget)
proc widget_bindings {} {
  global TH_Dir Bindings Class

  if {[lsearch "Entry Text Canvas" $Class] < 0} {return ""}
  set bindings ""

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

  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
