# jedit_menus.tcl - menus for jedit, a tk-based editor
#
######################################################################
# Copyright 1992-2000 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.     #
######################################################################

# the import IS A BIG PROBLEM until this whole file gets wrapped in its own
# namespace:

catch {
  package require jldb
  namespace import ::jldb::shortcuts::*
}

######################################################################
# INITIALISATION ON AUTOLOAD:

::jldb::set_defaults {
  {JEmenu:editor {Editor} 5}
  {JEmenu:file {File} 0}
  {JEmenu:edit {Edit} 0}
  {JEmenu:prefs {Prefs} 0}
  {JEmenu:abbrev {Abbrev} 0}
  {JEmenu:filter {Filter} 2}
  {JEmenu:format {Format} 3}
  {JEmenu:font {Font} 3}
  {JEmenu:background {Background} -1}
  {JEmenu:foreground {Foreground} -1}
  {JEmenucmd:underline {Underline} 0}
  {JEmenucmd:plain {Type in Plain} 9}
  {JEmenu:characters {Characters} -1}
  {JEmenu:user {User} 0}
  {JEmenu:help {Help} 0}
  {JEpref:show...menu {Show $menu menu}}
  {JEpref:savestate {Save/Load Visual State} 10}
  {JEpref:autobreak {Break Lines on <space>} 0}
  {JEpref:autoindent {Indent Lines on <Return>} 0}
  {JEpref:parenflash {Flash Matching Brackets} 0}
  {JEpref:sabbrev {Static Abbreviation} 1}
  {JEpref:dabbrev {Dynamic Abbreviation} 1}
  {JEpref:wrap_none {Don't wrap lines} 2}
  {JEpref:wrap_char {Wrap lines anywhere} 11}
  {JEpref:wrap_word {Wrap lines at words} 14}
  {{Help on jedit} {Help on jedit}}
  {{Help on Customisation} {Help on Customisation}}
  {{Help on Programming with jedit} {Help on Programming with jedit}}
  {{Help on aq} {Help on aq}}
}
jedit:register_commands

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

proc jedit:mkmenus {mb t} {
  ::aq::debug
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  set all_menus {editor file edit prefs abbrev filter format font mode1 mode2}
  set displayed_menus {}
  
  foreach menu $all_menus {
    if [winfo exists $mb.$menu] {
      destroy $mb.$menu
    }
    if $JEDIT_MODEPREFS($mode,menu,$menu) {
      jedit:mkmenu:$menu $mb.$menu $t
      catch {
        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 left
      lappend displayed_menus $mb.user
    }
  }
  
  # check for help menu at right of menubar
  #
  if $JEDIT_MODEPREFS($mode,menu,help) {
    if [winfo exists $mb.help] {
      destroy $mb.help
    }
    jedit:mkmenu:help $mb.help $t
    pack $mb.help -in $mb -side right
    lappend displayed_menus $mb.help
  }
  
  eval tk_menuBar $mb $displayed_menus
}

proc jedit:mkmenu:editor {menu t} {
  global JEDIT_MODEPREFS
  
  j:menu:menubutton $menu $menu.m JEmenu:editor
  
  j:menu:commands $menu.m $t {
    jedit:cmd:about
    ::aq::cmd::global_pref_panel
    jedit:cmd:edit_prefs
    jedit:cmd:mode_prefs
    jedit:cmd:ask_mode
    -
    ::aq::cmd::prompt_tcl
    ::aq::cmd::prompt_unix
  }
}

proc jedit:mkmenu:file {menu t} {
  global JEDIT_MODEPREFS
  global JEDIT_EMBEDDED
  global JEDIT_EMBEDDED_FILECOMMANDS
  
  j:menu:menubutton $menu $menu.m JEmenu:file
  
  if $JEDIT_EMBEDDED {
    j:menu:commands $menu.m $t $JEDIT_EMBEDDED_FILECOMMANDS
  } else {
    j:menu:commands $menu.m $t {
      jedit:cmd:load
      jedit:cmd:save
      jedit:cmd:saveas
      jedit:cmd:print
      -
      jedit:cmd:insfile
      -
      jedit:cmd:new_window
      jedit:cmd:done
      jedit:cmd:close
      jedit:cmd:quit
    }
  }
}

proc jedit:mkmenu:edit {menu t} {
  global JEDIT_MODEPREFS
  
  j:menu:menubutton $menu $menu.m JEmenu:edit
  
  jedit:mkmenu:edit:characters $menu.m.characters $t
  
  j:menu:commands $menu.m $t {
    jedit:cmd:cut
    jedit:cmd:copy
    jedit:cmd:paste
    jedit:cmd:note
    jedit:cmd:xpaste
    jedit:cmd:select_all
    -
    jedit:cmd:find
    jedit:cmd:find_again
    jedit:cmd:replace
    -
  }
  $menu.m add cascade \
    -label [= JEmenu:characters] \
    -menu $menu.m.characters
  j:menu:commands $menu.m $t {
    -
    jedit:cmd:go_to_line
    jedit:cmd:current_line
    -
    jedit:cmd:save_checkpoint
    jedit:cmd:undo
    jedit:cmd:redo
  }
  # the last three SHOULD BE affected by later configuration, and a trace
  # on JEDIT_PREFS(undolevel) (but aren't)
}

proc jedit:mkmenu:edit:characters { menu t } {
  menu $menu
  
  j:menu:commands $menu $t {
    jedit:cmd:char_panel
    jedit:cmd:hyphen
    jedit:cmd:copyright
  }
}

proc jedit:mkmenu:prefs {menu t} {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  j:menu:menubutton $menu $menu.m JEmenu:prefs
  
  j:menu:checkbuttons $menu.m \
    -command [list jedit:apply_prefs [jedit:text_to_top $t]] [list \
    [list JEpref:savestate JEDIT_MODEPREFS($mode,savestate)] \
    [list JEpref:autobreak JEDIT_MODEPREFS($mode,autobreak)] \
    [list JEpref:autoindent JEDIT_MODEPREFS($mode,autoindent)] \
    [list JEpref:parenflash JEDIT_MODEPREFS($mode,parenflash)] \
    - \
  ]
  j:menu:radiobuttons $menu.m \
    -command [list jedit:apply_prefs [jedit:text_to_top $t]] \
    -variable JEDIT_MODEPREFS($mode,textwrap) {
    {JEpref:wrap_none none}
    {JEpref:wrap_char char}
    {JEpref:wrap_word word}
  }
}

proc jedit:mkmenu:abbrev {menu t} {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  j:menu:menubutton $menu $menu.m JEmenu:abbrev
  
  j:menu:checkbuttons $menu.m [list \
    [list JEpref:sabbrev JEDIT_MODEPREFS($mode,sabbrev)] \
    [list JEpref:dabbrev JEDIT_MODEPREFS($mode,dabbrev)] \
  ]
  j:menu:commands $menu.m $t {
    -
    jedit:cmd:sabbrev
    jedit:cmd:dabbrev
    -
    jedit:cmd:edit_abbrevs
    jedit:cmd:read_abbrevs
  }
}

proc jedit:mkmenu:filter {menu t} {
  global JEDIT_MODEPREFS
  
  j:menu:menubutton $menu $menu.m JEmenu:filter
  
  j:menu:commands $menu.m $t {
    jedit:cmd:fmt
    -
    jedit:cmd:indent
    jedit:cmd:quote_email
    jedit:cmd:unindent
    -
    jedit:cmd:uppercase
    jedit:cmd:lowercase
    jedit:cmd:toggle_case
    -
    jedit:cmd:sort
    jedit:cmd:sort-n
    jedit:cmd:sort-if
    -
    jedit:cmd:run_pipe
    jedit:cmd:run_command
  }
}

proc jedit:mkmenu:format {menu t} {
  global JEDIT_MODEPREFS jedit_mkmenu_format
  
  j:menu:menubutton $menu $menu.m JEmenu:format
  
  jedit:mkmenu:format:font $menu.m.font $t
  jedit:mkmenu:format:background $menu.m.background $t
  jedit:mkmenu:format:foreground $menu.m.foreground $t
  
  $menu.m add cascade \
    -label [= JEmenu:font] \
    -menu $menu.m.font
  $menu.m add cascade \
    -label [= JEmenu:background] \
    -menu $menu.m.background
  $menu.m add cascade \
    -label [= JEmenu:foreground] \
    -menu $menu.m.foreground
  $menu.m add checkbutton \
    -label [= JEmenucmd:underline] \
    -underline [::jldb::underline JEmenucmd:underline] \
    -variable jedit_mkmenu_format(underline) \
    -command "jedit:format:underline $t \$jedit_mkmenu_format(underline)"
  $menu.m add separator
  $menu.m add command \
    -label [= JEmenucmd:plain] \
    -underline [::jldb::underline JEmenucmd:plain] \
    -command "::aq::tag::set_tags $t {}
    set jedit_mkmenu_format(underline) 0"
  j:menu:commands $menu.m $t {
    -
    jedit:format:list_item
    jedit:format:nest_list
    jedit:format:unnest_list
    -
    jedit:cmd:rich_saveas
    -
    jedit:cmd:print_postscript
  }
}

proc jedit:mkmenu:format:font {menu t} {
  global JEDIT_MODEPREFS
  
  menu $menu
  
  j:menu:commands $menu $t {
    jedit:font:plain
    -
    jedit:font:roman
    jedit:font:italic
    jedit:font:bold
    jedit:font:bolditalic
    jedit:font:typewriter
    -
    jedit:font:heading0
    jedit:font:heading1
    jedit:font:heading2
    jedit:font:heading3
    jedit:font:heading4
    jedit:font:heading5
    -
    jedit:font:l_em
    jedit:font:l_cite
    jedit:font:l_var
    jedit:font:l_dfn
    jedit:font:l_strong
    jedit:font:l_code
    jedit:font:l_samp
    jedit:font:l_kbd
  }
}

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

proc jedit:mkmenu:format:foreground { menu t } {
  global JEDIT_MODEPREFS
  
  menu $menu
  
  j:menu:commands $menu $t {
    jedit:format:foreground:clear
    -
  }
  
  set colours {
    #000000 #ffffff
    Black Grey25 Grey33 Grey50 Grey66 Grey75 White
    Red Green Blue Cyan Magenta Yellow
    LemonChiffon Gold SpringGreen
  }
  
  foreach colour $colours {
    $menu add command -label {        } \
      -background $colour \
      -activebackground $colour \
      -command [list jedit:format:foreground $t $colour]
  }
}

proc jedit:mkmenu:font {menu t} {
  global JEDIT_MODEPREFS
  
  j:menu:menubutton $menu $menu.m JEmenu:font
  
  j:menu:commands $menu.m $t {
    jedit:font:plain
    -
    jedit:font:roman
    jedit:font:italic
    jedit:font:bold
    jedit:font:bolditalic
    jedit:font:typewriter
    -
    jedit:font:heading0
    jedit:font:heading1
    jedit:font:heading2
    jedit:font:heading3
    jedit:font:heading4
    jedit:font:heading5
    -
    jedit:font:l_em
    jedit:font:l_cite
    jedit:font:l_var
    jedit:font:l_dfn
    jedit:font:l_strong
    jedit:font:l_code
    jedit:font:l_samp
    jedit:font:l_kbd
  }
}

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}
}


proc jedit:mkmenu:help {menu t} {
  global JEDIT_MODEPREFS
  
  set mode [jedit:get_mode $t]
  
  j:menu:menubutton $menu $menu.m JEmenu:help
  
  set documents {
    {{Help on jedit} {jedit.jdoc}}
    {{Help on Customisation} {jedit.jdoc#Customising_the_Editor}}
    {{Help on Programming with jedit} {jedit_prog.jdoc}}
  }
  set documents [concat $documents $JEDIT_MODEPREFS($mode,docs)]
  set documents [concat $documents {
    -
    {{Help on jstools} {jstools.jdoc}}
  }]
  
  j:menu:docs $menu.m $documents
}

######################################################################
# 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 font mode1 mode2 user} {
    checkbutton $w.$menu -anchor w \
      -text [subst -nobackslashes -nocommands [= JEpref:show...menu]] \
      -variable JEDIT_MODEPREFS($mode,menu,$menu)
    pack $w.$menu -expand y -fill x
  }
  
  return $w
}
