# jedit_menus.tcl - menus for jedit, a tk-based editor
# 
# Copyright 1992-1995 by Jay Sekora.  All rights reserved, except 
# that this file may be freely redistributed in whole or in part 
# for non-profit, noncommercial use.

######################################################################
# jedit:mkmenus - create menubar
######################################################################

proc jedit:mkmenus {mb t} {
  j:debug
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  set all_menus {editor file edit prefs abbrev filter format mode1 mode2}
  set displayed_menus {}
  
  foreach menu $all_menus {
    if [winfo exists $mb.$menu] {
      destroy $mb.$menu
    }
    if $JEDIT_MODEPREFS($mode,menu,$menu) {
      catch {
        jedit:mkmenu:$menu $mb.$menu $t
        pack $mb.$menu -in $mb -side left
        lappend displayed_menus $mb.$menu
      }
    }
  }
  
  # check for user menu proc - normally in ~/.tk/jeditrc.tcl
  #
  if $JEDIT_MODEPREFS($mode,menu,user) {
    if {[info procs jedit:mkmenu:user] != {}} {
      if [winfo exists $mb.user] {
        destroy $mb.user
      }
      jedit:mkmenu:user $mb.user $t
      pack $mb.user -in $mb -side right
      lappend displayed_menus $mb.user
    }
  }
  
  eval tk_menuBar $mb $displayed_menus
}

proc jedit:mkmenu:editor {menu t} {
  global JEDIT_MODEPREFS
  
  menubutton $menu -text {Editor} -menu $menu.m
  
  menu $menu.m
  
  $menu.m add command -label {Help} -accelerator {[h]} \
    -command "jedit:cmd:help $t"
  $menu.m add command -label {About the Editor . . .} \
    -command "jedit:cmd:about $t"
  $menu.m add command -label {Global Preferences . . .} \
    -accelerator {[G]} \
    -command {j:global_pref_panel}
  $menu.m add command -label {Editor Preferences . . .} \
    -accelerator {[P]} \
    -command "jedit:cmd:edit_prefs $t"
  $menu.m add command -label {Mode Preferences . . .} \
    -command "jedit:cmd:mode_prefs $t"
  $menu.m add command -label {Mode . . .} -accelerator {[m]} \
    -command "jedit:cmd:ask_mode $t"
  $menu.m add separator
  $menu.m add command -label {Issue Tcl Command . . .} \
    -accelerator {[T]} -command {j:prompt_tcl}
  $menu.m add command -label {Issue Unix Command . . .} \
    -accelerator {[U]} -command {j:prompt_unix}
  $menu.m add separator
  $menu.m add command -label {New Window} -accelerator {[n]} \
    -command "jedit:cmd:new_window $t"
  $menu.m add command -label {Done} \
    -command "jedit:cmd:done $t"
  $menu.m add command -label {Close Window} -accelerator {[w]} \
    -command "jedit:cmd:close $t"
  $menu.m add command -label {Quit} -accelerator {[q]} \
    -command "jedit:cmd:quit $t"
}

proc jedit:mkmenu:file {menu t} {
  global JEDIT_MODEPREFS
  
  menubutton $menu -text {File} -menu $menu.m
  
  menu $menu.m
  
  $menu.m add command -label {Load . . .} -accelerator {[l]} \
    -command "jedit:cmd:load $t"
  $menu.m add command -label {Save} -accelerator {[s]} \
    -command "jedit:cmd:save $t"
  $menu.m add command -label {Save As . . .} -accelerator {[S]} \
    -command "jedit:cmd:saveas $t"
  $menu.m add command -label {Print . . .} -accelerator {[p]} \
    -command "jedit:cmd:print $t"
  $menu.m add separator
  $menu.m add command -label {Insert File . . .} -accelerator {[i]} \
    -command "jedit:cmd:insfile $t"
}

proc jedit:mkmenu:edit {menu t} {
  global JEDIT_MODEPREFS
  
  menubutton $menu -text {Edit} -menu $menu.m
  
  menu $menu.m
  
  $menu.m add command -label {Cut} -accelerator {[x]} \
    -command "jedit:cmd:cut $t"
  $menu.m add command -label {Copy} -accelerator {[c]} \
    -command "jedit:cmd:copy $t"
  $menu.m add command -label {Paste} -accelerator {[v]} \
    -command "jedit:cmd:paste $t"
  $menu.m add command -label {Note} -accelerator {[N]} \
    -command "jedit:cmd:note $t"
  $menu.m add command -label {Insert X Selection} -accelerator {[V]} \
    -command "jedit:cmd:xpaste $t"
  $menu.m add command -label {Select All} -accelerator {[a]} \
    -command "jedit:cmd:select_all $t"
  $menu.m add separator
  $menu.m add command -label {Find . . .} -accelerator {[f]} \
    -command "jedit:cmd:find $t"
  $menu.m add command -label {Find Again} -accelerator {[g]} \
    -command "jedit:cmd:find_again $t"
  $menu.m add separator
  $menu.m add command -label {Go to Line . . .} -accelerator {[L]} \
    -command "jedit:cmd:go_to_line $t"
  $menu.m add command \
    -label {Show Current Position . . .} -accelerator {[C]} \
    -command "jedit:cmd:current_line $t"
  $menu.m add separator
  #
  # the following three SHOULD BE affected by later configuration, and a trace
  # on JEDIT_PREFS(undolevel) (but aren't)
  #
  $menu.m add command -label {Checkpoint} \
    -command "jedit:cmd:save_checkpoint $t"
  $menu.m add command -label {Undo} -accelerator {[z]} \
    -command "jedit:cmd:undo $t"
  $menu.m add command -label {Redo} -accelerator {[Z]} \
    -command "jedit:cmd:redo $t"
}

proc jedit:mkmenu:prefs {menu t} {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  menubutton $menu -text {Prefs} -menu $menu.m
  
  menu $menu.m
  
  $menu.m add checkbutton -label {Save/load visual state} \
    -variable JEDIT_MODEPREFS($mode,savestate) \
    -command "jedit:apply_prefs \[jedit:text_to_top $t\]"
  $menu.m add checkbutton -label {Break lines on <space>} \
    -variable JEDIT_MODEPREFS($mode,autobreak) \
    -command "jedit:apply_prefs \[jedit:text_to_top $t\]"
  $menu.m add checkbutton -label {Indent lines on <Return>} \
    -variable JEDIT_MODEPREFS($mode,autoindent) \
    -command "jedit:apply_prefs \[jedit:text_to_top $t\]"
  $menu.m add separator
  $menu.m add radiobutton -label {Don't wrap lines} \
    -variable JEDIT_MODEPREFS($mode,textwrap) -value none \
    -command "jedit:apply_prefs \[jedit:text_to_top $t\]"
  $menu.m add radiobutton -label {Wrap lines anywhere} \
    -variable JEDIT_MODEPREFS($mode,textwrap) -value char \
    -command "jedit:apply_prefs \[jedit:text_to_top $t\]"
  $menu.m add radiobutton -label {Wrap lines at words} \
    -variable JEDIT_MODEPREFS($mode,textwrap) -value word \
    -command "jedit:apply_prefs \[jedit:text_to_top $t\]"
}

proc jedit:mkmenu:abbrev {menu t} {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  menubutton $menu -text {Abbrev} -menu $menu.m
  
  menu $menu.m
  
  $menu.m add checkbutton -label {Static Abbreviation} \
    -accelerator {[Space]} \
    -variable JEDIT_MODEPREFS($mode,sabbrev) -onvalue 1 -offvalue 0
  $menu.m add checkbutton -label {Dynamic Abbreviation} \
    -accelerator {[Tab]} \
    -variable JEDIT_MODEPREFS($mode,dabbrev) -onvalue 1 -offvalue 0
  $menu.m add separator
  $menu.m add command -label {Expand Static Abbreviation} \
    -accelerator {[']} \
    -command "jedit:cmd:sabbrev $t"
  $menu.m add command -label {Expand Dynamic Abbreviation} \
    -accelerator {[;]} \
    -command "jedit:cmd:dabbrev $t"
  $menu.m add separator
  $menu.m add command -label {Edit Static Abbreviations} \
    -command "jedit:cmd:edit_abbrevs"
  $menu.m add command -label {Reread Static Abbreviations} \
    -command "jedit:cmd:read_abbrevs"
}

proc jedit:mkmenu:filter {menu t} {
  global JEDIT_MODEPREFS
  
  menubutton $menu -text {Filter} -menu $menu.m
  
  menu $menu.m
  
  $menu.m add command -label {Format Lines with `fmt'} \
    -accelerator {[F]} \
    -command "jedit:pipe $t {fmt}"
  $menu.m add separator
  #
  # following few entries are tricky syntactically.  the commands are in
  # quotes, so double-quote-style substitution is done on the ENTIRE
  # command (braces aren't special in quotes).
  #
  $menu.m add command -label {Indent} \
    -accelerator {[]]} \
    -command "jedit:text_regsub $t {(^|\n)} {\\1  }"
  $menu.m add command -label {Quote Email} \
    -command "jedit:text_regsub $t {(^|\n)} {\\1> }"
  $menu.m add command -label {Unindent/Unquote} \
    -accelerator {[[]} \
    -command "jedit:text_regsub $t {(^|\n)\[> \] } {\\1}"
  #
  $menu.m add separator
  $menu.m add command -label {Capitalise} \
    -command "jedit:pipe $t {tr {\[a-z\]} {\[A-Z\]}}"
  $menu.m add command -label {Lowercase} \
    -command "jedit:pipe $t {tr {\[A-Z\]} {\[a-z\]}}"
  $menu.m add command -label {Toggle Case} \
    -command "jedit:pipe $t {tr {\[A-Z\]\[a-z\]} {\[a-z\]\[A-Z\]}}"
  $menu.m add separator
  $menu.m add command -label {Sort by ASCII Sequence} \
    -command "jedit:pipe $t {sort}"
  $menu.m add command -label {Sort Numerically} \
    -command "jedit:pipe $t {sort -n}"
  $menu.m add command -label {Sort Alphabetically} \
    -command "jedit:pipe $t {sort -if}"
  $menu.m add separator
  $menu.m add command -label {Pipe Through . . .} -accelerator {[|]} \
     -command "jedit:cmd:run_pipe $t"
  $menu.m add command -label {Insert Output of . . .} -accelerator {[!]} \
     -command "jedit:cmd:run_command $t"
}

proc jedit:mkmenu:format {menu t} {
  global JEDIT_MODEPREFS jedit_mkmenu_format
  
  menubutton $menu -text {Format} -menu $menu.m
  
  menu $menu.m
  
  jedit:mkmenu:format:font $menu.m.font $t
  jedit:mkmenu:format:background $menu.m.background $t
  jedit:mkmenu:format:foreground $menu.m.foreground $t
  jedit:mkmenu:format:characters $menu.m.characters $t
  
  $menu.m add command -label "Rich Cut" -command "jedit:cmd:rich_cut $t"
  $menu.m add command -label "Rich Copy" -command "jedit:cmd:rich_copy $t"
  $menu.m add command -label "Rich Paste" -command "jedit:cmd:rich_paste $t"
  $menu.m add separator
  $menu.m add cascade -label "Font" -menu $menu.m.font
  $menu.m add cascade -label "Background" -menu $menu.m.background
  $menu.m add cascade -label "Foreground" -menu $menu.m.foreground
  $menu.m add checkbutton -label "Underline" \
    -variable jedit_mkmenu_format(underline) \
    -command "jedit:format:underline $t \$jedit_mkmenu_format(underline)"
  $menu.m add separator
  $menu.m add command -label {Type in Plain} \
    -command "j:tag:set_tags $t {}; set jedit_mkmenu_format(underline) 0"
  $menu.m add separator
  $menu.m add cascade -label "Characters" -menu $menu.m.characters
  $menu.m add separator
  $menu.m add command -label "Rich Save As . . ." -command "j:tc:saveas $t"
  $menu.m add separator
  $menu.m add command -label "Print PostScript" \
    -command "jedit:cmd:print_postscript $t"
}

proc jedit:mkmenu:format:font {menu t} {
  global JEDIT_MODEPREFS
  
  menu $menu
  
  $menu add command -label {Roman} \
    -accelerator {[R]} \
    -command "jedit:font:roman $t"
  $menu add command -label {Italic} \
    -accelerator {[I]} \
    -command "jedit:font:italic $t"
  $menu add command -label {Bold} \
    -accelerator {[B]} \
    -command "jedit:font:bold $t"
  $menu add command -label {Bold Italic} \
    -accelerator {[X]} \
    -command "jedit:font:bolditalic $t"
  $menu add command -label {Typewriter} \
    -accelerator {[M]} \
    -command "jedit:font:typewriter $t"
  $menu add separator
  $menu add command -label {Level 0 Heading} \
    -command "jedit:font:heading0 $t"
  $menu add command -label {Level 1 Heading} \
    -command "jedit:font:heading1 $t"
  $menu add command -label {Level 2 Heading} \
    -command "jedit:font:heading2 $t"
  $menu add command -label {Level 3 Heading} \
    -command "jedit:font:heading3 $t"
  $menu add command -label {Level 4 Heading} \
    -command "jedit:font:heading4 $t"
  $menu add command -label {Level 5 Heading} \
    -command "jedit:font:heading5 $t"
  $menu add separator
  $menu add command -label {Plain Font} \
    -command "jedit:font:plain $t"
}

proc jedit:mkmenu:format:background {menu t} {
  global JEDIT_MODEPREFS
  
  menu $menu
  
  $menu add command -label {Plain Background} \
    -command "jedit:format:background:clear $t"
  $menu add separator
  
  set colours {
    Black Grey25 Grey33 Grey50 Grey66 Grey75 White
    Red Green Blue Cyan Magenta Yellow
    LemonChiffon Gold SpringGreen
  }
  
  foreach colour $colours {
    $menu add command -label $colour \
      -command [list jedit:format:background $t $colour]
  }
}

proc jedit:mkmenu:format:foreground { menu t } {
  global JEDIT_MODEPREFS
  
  menu $menu
  
  $menu add command -label {Plain Foreground} \
    -command "jedit:format:foreground:clear $t"
  $menu add separator
  
  set colours {
    Black Grey25 Grey33 Grey50 Grey66 Grey75 White
    Red Green Blue Cyan Magenta Yellow
    LemonChiffon Gold SpringGreen
  }
  
  foreach colour $colours {
    $menu add command -label $colour \
      -command [list jedit:format:foreground $t $colour]
  }
}

proc jedit:mkmenu:format:characters { menu t } {
  menu $menu
  
  $menu add command -label "Select Character . . ." \
    -command "jedit:cmd:char_panel $t"
  $menu add command -label "Insert Hyphen" \
    -accelerator {[-]} \
    -command "jedit:cmd:hyphen $t"
  $menu add command -label "Insert Copyright Symbol" \
    -command "jedit:cmd:copyright $t"
}

proc jedit:mkmenu:mode1 { menu t } {
  set mode [jedit:get_mode $t]
  
  #####################  should check for proc, not just catch! ##############
  catch {eval mode:$mode:mkmenu1 $menu $t}
}

proc jedit:mkmenu:mode2 { menu t } {
  set mode [jedit:get_mode $t]
  
  #####################  should check for proc, not just catch! ##############
  catch {eval mode:$mode:mkmenu2 $menu $t}
}

######################################################################
# jedit:menus:prefs w mode- return mode menu preferences metawidget
######################################################################

proc jedit:prefs:menus { w mode } {
  global JEDIT_MODEPREFS
  
  frame $w
  foreach menu {file edit prefs abbrev filter format mode1 mode2 user} {
    checkbutton $w.$menu -relief flat -anchor w \
      -text "Show $menu menu" \
      -variable JEDIT_MODEPREFS($mode,menu,$menu)
    pack $w.$menu -expand y -fill x
  }
  
  return $w
}
