# jmore.tcl - text display panel
#
######################################################################
# Copyright 1992-2002 by Jay Sekora.  This file may be freely        #
# distributed, modified or unmodified, for any purpose, provided     #
# that this copyright notice is retained verbatim in all copies and  #
# no attempt is made to obscure the authorship of this file.  If you #
# distribute any modified versions, I ask, but do not require, that  #
# you clearly mark any changes you make as such and that you provide #
# your users with instructions for getting the original sources.     #
######################################################################

### TO DO
###   ::aq::more_button to add a button to the buttonbar
###   fix focus problems

package provide aq 0.1

# following has side-effect of making sure ::aq namespace is defined
namespace eval ::aq {
  namespace export {[a-z]*}
  catch {
    package require jldb
    # following likely to fail, because done by other libraries too
    namespace import ::jldb::shortcuts::*
  }
}

######################################################################
# global variables:
#
global J_PREFS env
::aq::default J_PREFS(autoposition) 0
::aq::default J_PREFS(confirm) 1
::aq::default J_PREFS(printer) lp
#
######################################################################


######################################################################
# ::aq::more ?options? ?-title hdr? ?-text txt? - displays text in window
# options include
#   -title (default "Output")
#   -text (default "" - not really optional)
#   -annotation (default "")
#   -height (default 24)
#   -width (default 80)
#   -font (default "default")
#   -class (default "More")
# this unfortunately forces focus-follows-pointer in these windows
######################################################################

proc ::aq::more { args } {
  global J_PREFS
  global AQSYSINFO
  if {[lsearch [array names J_PREFS] {scrollbarside}] == -1} {
    set J_PREFS(scrollbarside) right ;# make sure it's defined
  }

  ::aq::parse_args {
    {title Output}
    {text {}}
    {annotation {}}
    {wrap char}
    {height 24}
    {width 80}
    {font default}
    {class More}
  }
  
  global j_more

  if {[info exists j_more(count)]} then {
    set j_more(count) [expr {$j_more(count) + 1}]
  } else {
    set j_more(count) 0
  }

  set w ".more$j_more(count)"

  toplevel $w -class $class
  if {$AQSYSINFO(tinyscreen)} {
    wm minsize $w $AQSYSINFO(min_width) $AQSYSINFO(min_height)
  }
  
  # the subst below is so $title can contain $filename
  wm title $w [uplevel #0 \
    [format {subst -nobackslashes -nocommands {%s}} $title]]
  
  # using ::aq::buttonbar for visual consistency; we can't (easily)
  # set the commands with it (because they depend on the window name):
  
  ::aq::buttonbar $w.b -default ok -buttons {
    {ok more:done {}}
    {save more:save {}}
    {print more:print {}}
    {find more:find {}}
  }
  
  $w.b.ok configure -command "destroy $w"
  $w.b.save configure -command "::aq::_more_save $w"
  $w.b.print configure -command "::aq::_more_print $w"
  $w.b.find configure -command "::aq::find -replace 0 $w.t"
  
  scrollbar $w.sb -command "$w.t yview"
  text $w.t -yscrollcommand "$w.sb set" -wrap word \
    -height $height -wrap $wrap -width $width
  if {!$AQSYSINFO(tinyscreen)} {
    $w.t configure -setgrid true
  }
  ::aq::configure_font $w.t [list $font]
  
  pack \
    $w.b \
    -side bottom -fill x
  pack \
    $w.sb \
    -side $J_PREFS(scrollbarside) -fill y
  pack \
    $w.t \
    -expand yes -fill both
  
  $w.t insert end $text
  
  if [string length $annotation] {
    ::aq::tag::set_annotation $w.t $annotation
    ::aq::tag::configure_display_tags $w.t
    ::aq::tag::configure_fonts $w.t
  }
  
  $w.t mark set insert 1.0
  $w.t yview 1.0
  $w.t tag remove sel 1.0 end
  
  $w.t configure -state disabled ;# prevent its being edited
  
  # FOLLOWING BINDINGS SHOULD BE GENERALISED! and check J_PREFS(bindings)!
  #
  bind $w.t <Next> "::aq::_more_pageup $w.t"
  bind $w.t <space> "::aq::_more_pageup $w.t"
  bind $w.t <Control-v> "::aq::_more_pageup $w.t"
  
  bind $w.t <Prior> "::aq::_more_pagedown $w.t"
  bind $w.t <b> "::aq::_more_pagedown $w.t"
  bind $w.t <Escape><v> "::aq::_more_pagedown $w.t"
  
  # "cancel" and "ok" amount to the same thing for this window:
  ::aq::default_button $w.b.ok $w.t
  ::aq::cancel_button $w.b.ok $w.t
  
  # restore old focus when window is destroyed (note that the [focus]
  #   is evaluated _now_)
  bind $w <Destroy> [list catch catch [list focus -force [focus]]]
  
  catch [list focus $w.t]
  
  return $w.t			;# so caller can insert things in it
}

######################################################################
# ::aq::_more_save w - save content of a ::aq::more window
#   NOTE: this adds a newline!  should check if ends in newline alr.
######################################################################

proc ::aq::_more_save { w } {
  set filename [::aq::fs]
  if {$filename == {}	} {
    return 1
  }
  # should do error checking
  set file [open $filename {w}]
  puts $file [$w.t get 1.0 end]
  close $file
}

######################################################################
# ::aq::_more_print w - print the content of a ::aq::more window
#   command to use should be a preference!
# uses J_PREFS(printer)
######################################################################

proc ::aq::_more_print { w } {
  global env J_PREFS
  
  append J_PREFS(printer) {}			;# make sure it's defined
  if {"x$J_PREFS(printer)" == "x"} then {set J_PREFS(printer) "lp"}
  
  if [::aq::confirm -priority 100 \
    -text [subst [= confirm:print \
      "Print using lpr to $J_PREFS(printer)?"]]] {
    # should do error checking
    set file [open "|lpr -P$J_PREFS(printer)" {w}]
    puts $file [$w.t get 1.0 end] nonewline
    close $file
  }
}

######################################################################
# ::aq::_more_pageup t - scrolls text widget t up
######################################################################

proc ::aq::_more_pageup { t } {
  $t yview scroll 1 page
  $t mark set insert @0,0
  $t see insert
}

######################################################################
# ::aq::_more_pagedown t - scrolls text widget t down
######################################################################

proc ::aq::_more_pagedown { t } {
  $t yview scroll -1 page
  $t mark set insert @0,0
  $t see insert
}
