#-------------------------------------------------------------------------
# Start of xcircuit GUI configuration file.
# This file is sourced by "xcircuit.tcl" (".wishrc")
#-------------------------------------------------------------------------

# This script sets up all the xcircuit windows and callback functions.
# The callback routines are in the shared object file xcwrap.so

#-------------------------------
# Main xcircuit drawing window
#-------------------------------

toplevel .xcircuit
wm title .xcircuit XCircuit
wm protocol .xcircuit WM_DELETE_WINDOW quit

# This gets rid of the original "wish", in favor of our own window

if {[string range [wm title .] 0 3] == "wish"} {
   wm withdraw .
}

# All the internal frames

frame .xcircuit.menubar -background red
frame .xcircuit.infobar -background red
frame .xcircuit.mainframe -background red

pack propagate .xcircuit false

pack .xcircuit.menubar -side top -fill x -pady 1
pack .xcircuit.mainframe -side top -expand true -fill both
pack .xcircuit.infobar -side bottom -fill x -pady 1

frame .xcircuit.mainframe.mainarea -background red
frame .xcircuit.mainframe.toolbar -bg beige

pack .xcircuit.mainframe.toolbar -side right -fill y -padx 2
pack .xcircuit.mainframe.mainarea -expand true -fill both

simple .xcircuit.mainframe.mainarea.sbleft -width 13 -bg beige
simple .xcircuit.mainframe.mainarea.sbbottom -height 13 -bg beige
simple .xcircuit.mainframe.mainarea.drawing -bg white -exitproc "quitnocheck"
simple .xcircuit.mainframe.mainarea.corner -width 13 -height 13 -bg black

# The drawing area and its scrollbars

grid .xcircuit.mainframe.mainarea.sbleft -row 0 -column 0 -sticky ns -padx 1
grid .xcircuit.mainframe.mainarea.sbbottom -row 1 -column 1 -sticky ew -pady 1
grid .xcircuit.mainframe.mainarea.drawing -row 0 -column 1 -sticky news
grid .xcircuit.mainframe.mainarea.corner -row 1 -column 0 -sticky news

grid rowconfigure .xcircuit.mainframe.mainarea 0 -weight 1
grid columnconfigure .xcircuit.mainframe.mainarea 1 -weight 1

# The top menu and message bar

menubutton .xcircuit.menubar.filebutton -text File \
	-menu .xcircuit.menubar.filebutton.filemenu
menubutton .xcircuit.menubar.editbutton -text Edit \
	-menu .xcircuit.menubar.editbutton.editmenu
menubutton .xcircuit.menubar.textbutton -text Text \
	-menu .xcircuit.menubar.textbutton.textmenu
menubutton .xcircuit.menubar.optionsbutton -text Options \
	-menu .xcircuit.menubar.optionsbutton.optionsmenu
menubutton .xcircuit.menubar.windowbutton -text Window \
	-menu .xcircuit.menubar.windowbutton.windowmenu
menubutton .xcircuit.menubar.netlistbutton -text Netlist \
	-menu .xcircuit.menubar.netlistbutton.netlistmenu 

pack .xcircuit.menubar.filebutton .xcircuit.menubar.editbutton \
	.xcircuit.menubar.textbutton .xcircuit.menubar.optionsbutton \
	.xcircuit.menubar.windowbutton .xcircuit.menubar.netlistbutton \
	-side left -padx 2 -ipadx 10 -pady 2

# The bottom message bar

label .xcircuit.menubar.message -text \
	"Welcome to Xcircuit v${XCIRCUIT_VERSION} rev ${XCIRCUIT_REVISION}" \
	-background beige -justify left -anchor w
pack .xcircuit.menubar.message -side top -fill x -padx 2 -ipady 3 -pady 2

button .xcircuit.infobar.symb -text "Symbol" -bg gray30 -fg white
button .xcircuit.infobar.schem -text "Schematic" -bg red -fg white
label .xcircuit.infobar.mode -text "Wire Mode" -bg skyblue2 -fg gray20
label .xcircuit.infobar.message1 -text "Editing: Page 1" \
	-background beige
label .xcircuit.infobar.message2 -text "Grid 1/6 in : Snap 1/12 in" \
	-background beige -justify left -anchor w
pack .xcircuit.infobar.symb .xcircuit.infobar.schem .xcircuit.infobar.mode \
	.xcircuit.infobar.message1 -side left -padx 2 -ipadx 6 -fill y
pack .xcircuit.infobar.message2 -padx 2 -ipadx 6 -expand true -fill both

#----------------------------------------------------------------------
# Support procedures for tag callbacks
#----------------------------------------------------------------------

proc xcircuit::popupdialog {} {
   xcircuit::removeliblist .dialog
   wm deiconify .dialog
   focus .dialog.textent.txt
}

proc xcircuit::popupfilelist {} {
   xcircuit::removeliblist .filelist
   wm deiconify .filelist
   focus .filelist.textent.txt
}

# This procedure configures the output properties window according to
# the page mode (full or encapsulated)

proc xcircuit::setpstype {mode} {
   global XCOps
   switch -- $mode {
      {eps} { .output.textent.butp configure -text "Embedded (EPS)"
	 grid remove .output.textent.but7
	 grid remove .output.textent.butf
	 grid remove .output.textent.txtf
      }
      {full} {.output.textent.butp configure -text "Full Page"
	 grid .output.textent.but7 -row 6 -column 3 -pady 5 -ipadx 10
	 grid .output.textent.butf -row 5 -column 2 -padx 10
	 grid .output.textent.txtf -row 6 -column 2 -sticky ew -padx 10
      }
   }
   set XCOps(pstype) $mode
   xcircuit::page encapsulation $mode
}

proc xcircuit::dolinks {} {
   global XCOps
   set ilinks [xcircuit::page links independent]
   if {$ilinks > 1} {
      set XCOps(imultiple) 1
   } else {
      set XCOps(imultiple) 0
   }
   if {$ilinks == 1} { set plural ""} else { set plural "s"}
   .output.title.imulti configure -text "$ilinks schematic$plural"

   if {$XCOps(dmultiple) == 1} {
      set dlinks [xcircuit::page links dependent]
   } else {
      set dlinks 0
   }
   if {$dlinks == 1} { set plural ""} else { set plural "s"}
   .output.title.dmulti configure -text "$dlinks subcircuit$plural"
}

proc xcircuit::pageupdate { {subcommand "none"} } {
   global tcl_precision XCOps
   if {[info level] <= 1} {
     switch -- $subcommand {
	save {
	   .output.bbar.okay configure -text "Done"
	   .output.bbar.okay configure -command {wm withdraw .output}
	}
	make {
	   xcircuit::newpagebutton [xcircuit::page label]
	}
	default {
	  .output.title.field configure -text \
		"PostScript output properties (Page [xcircuit::page])"
	  set fname [xcircuit::page filename]
	  .output.textent.but1 configure -text Apply
	  .output.textent.but2 configure -text Apply
	  .output.textent.but3 configure -text Apply
	  .output.textent.but4 configure -text Apply
	  .output.textent.but5 configure -text Apply
	  .output.textent.but7 configure -text Apply
	  .output.textent.txt1 delete 0 end
	  .output.textent.txt1 insert 0 $fname
	  .output.textent.txt2 delete 0 end
	  .output.textent.txt2 insert 0 [xcircuit::page label]
	  .output.textent.txt3 delete 0 end
	  set oldp $tcl_precision
	  set tcl_precision 5
	  .output.textent.txt3 insert 0 [xcircuit::page scale]
	  .output.textent.txt4 delete 0 end
	  set tcl_precision 3
	  .output.textent.txt4 insert 0 [xcircuit::page width]
	  .output.textent.txt4 insert end " "
	  .output.textent.txt4 insert end [xcircuit::coordstyle get]
	  .output.textent.txt5 delete 0 end
	  .output.textent.txt5 insert 0 [xcircuit::page height]
	  .output.textent.txt5 insert end " "
	  .output.textent.txt5 insert end [xcircuit::coordstyle get]
	  .output.textent.txtf.txtp delete 0 end
	  .output.textent.txtf.txtp insert 0 [xcircuit::page size]
	  set tcl_precision $oldp
	  xcircuit::setpstype [xcircuit::page encapsulation]
	  set XCOps(orient) [xcircuit::page orientation]
	  if {$XCOps(orient) == 0} {
	     .output.textent.buto configure -text Portrait
	  } else {
	     .output.textent.buto configure -text Landscape
	  }
	  xcircuit::dolinks

	  set autofit [xcircuit::page fit]
	  if {[string match *.* $fname] == 0} {append fname .ps}
	  if {[glob -nocomplain ${fname}] == {}} {
	    .output.bbar.okay configure -text "Write File"
	  } else {
	    .output.bbar.okay configure -text "Overwrite File"
	  }
	  .output.bbar.okay configure -command \
		{.output.textent.but1 invoke; \
		 .output.textent.but2 invoke; \
		 if {$XCOps(dmultiple) == 1} {xcircuit::page save} else { \
		 xcircuit::page saveonly }; wm withdraw .output}
        }
     }
  }
}

#----------------------------------------------------------------------
# Update the GUI based on the schematic class of the current page
# This is called internally from the xcircuit code and the function
# must be defined, even if it is a null proc.
#----------------------------------------------------------------------

proc xcircuit::setsymschem {} {
   if {[info level] <= 1} {
      set schemtype [xcircuit::schematic type]
      set symschem [xcircuit::schematic get]
      set m .xcircuit.menubar.netlistbutton.netlistmenu
      switch -- $schemtype {
         primary -
	 secondary -
	 schematic {
	    .xcircuit.infobar.schem configure -background red -foreground white
	    if {$symschem == {}} {
		.xcircuit.infobar.symb configure -background gray70 -foreground gray40
		$m entryconfigure 5 -label "Make Matching Symbol" \
			-command {xcircuit::promptmakesymbol [page label]}
		$m entryconfigure 6 -label "Associate With Symbol" \
			-command {xcircuit::symbol associate}
	    } else {
		.xcircuit.infobar.symb configure -background white -foreground black
		$m entryconfigure 5 -label "Go To Symbol" \
			-command {xcircuit::symbol go}
		$m entryconfigure 6 -label "Disassociate Symbol" \
			-command {xcircuit::symbol disassociate}
	    }
	 }
	 symbol -
	 fundamental -
	 trivial {
	    .xcircuit.infobar.symb configure -foreground white
	    if {$symschem == {}} {
		.xcircuit.infobar.schem configure -background gray70 -foreground gray40
		$m entryconfigure 5 -label "Make Matching Schematic" \
			-command {xcircuit::schematic make}
		$m entryconfigure 6 -label "Associate With Schematic" \
			-command {xcircuit::schematic associate}
	    } else {
		.xcircuit.infobar.schem configure -background white -foreground black
		$m entryconfigure 5 -label "Go To Schematic" \
			-command {xcircuit::schematic go}
		$m entryconfigure 6 -label "Disassociate Schematic" \
			-command {xcircuit::schematic disassociate}
	    }
	 }
      }
      switch -- $schemtype {
	 trivial {
	    .xcircuit.infobar.symb configure -background red
	 }
	 fundamental {
	    .xcircuit.infobar.symb configure -background green4 ;# bboxcolor
	 }
	 symbol {
	    .xcircuit.infobar.symb configure -background blue2 
	 }
      }
   }
}
   
#----------------------------------------------------------------------
# Set the coordinate style to inches from cm and vice versa.
# This routine avoids switching from fractional to decimal inches
# and vice versa if we are already in one of the two inches modes.
#
# with no argument, or argument "get", returns the "short" name
# ("cm" or "in") of the style.
#----------------------------------------------------------------------

proc xcircuit::coordstyle { { mode get } } {
   set curstyle [xcircuit::config coordstyle]
   switch -- $mode {
      inches {
	 switch -- $curstyle {
	    centimeters {
	       xcircuit::config coordstyle "decimal inches"
	       xcircuit::pageupdate
	    }
	 }
      }
      centimeters -
      cm {
	 switch -- $curstyle {
	    centimeters {
	    }
	    default {
	       xcircuit::config coordstyle "centimeters"
	       xcircuit::pageupdate
	    }
	 }
      }
      get {
	 switch -- $curstyle {
	    centimeters {
	       return "cm"
	    }
	    default {
	       return "in"
	    }
	 }
      }
   }
}

proc xcircuit::raiseconsole {} {
   xcircuit::consoleup
   set cidx [.xcircuit.menubar.filebutton.filemenu index *Console]
   .xcircuit.menubar.filebutton.filemenu entryconfigure \
	 $cidx -label "No Console" -command {xcircuit::lowerconsole}
}

proc xcircuit::lowerconsole {} {
   xcircuit::consoledown
   set cidx [.xcircuit.menubar.filebutton.filemenu index *Console]
   .xcircuit.menubar.filebutton.filemenu entryconfigure \
	 $cidx -label "Tcl Console" -command {xcircuit::raiseconsole}
}

#----------------------------------------------------------------------
# Command tags---these let the command-line entry functions update the
# Tk windows, so that the Tk window structure doesn't need to be hard-
# coded into the source.
#----------------------------------------------------------------------

xcircuit::tag page {xcircuit::pageupdate %1}
xcircuit::tag promptchecksavelib {xcircuit::promptsavelib %r}
xcircuit::tag promptsavepage {xcircuit::pageupdate ; wm deiconify .output ; \
	raise .output}
xcircuit::tag loadfont {xcircuit::newfontbutton %r}
xcircuit::tag color { if {"%1" == "set"} { \
	set XCOps(colorval) %2; set iname img_co; \
	if {"%2" != "inherit"} {append iname l%2} ; \
	.xcircuit.mainframe.toolbar.bco configure -image $iname} }
xcircuit::tag fill { foreach i %N { switch -- "$i" { \
	   opaque { set XCOps(opaque) true } \
	   transparent { set XCOps(opaque) false } 0 - unfilled \
		{set XCOps(fillamount) 0; \
	      .xcircuit.mainframe.toolbar.bfi configure -image img_fi} \
	   solid {set XCOps(fillamount) 100; \
	      .xcircuit.mainframe.toolbar.bfi configure -image img_stip100}
	   default {set XCOps(fillamount) $i; \
	      .xcircuit.mainframe.toolbar.bfi configure -image img_stip$i} } } }
xcircuit::tag parameter { if {"%1" == "set"} {xcircuit::prompteditparams \
		{substring numeric expression}} }

#------------------------------
# Create the file-list window
#------------------------------

# First, set the variables associated with toggle and radio buttons
set XCOps(filter) 1

toplevel .filelist -bg beige
wm withdraw .filelist

frame .filelist.listwin
frame .filelist.textent -bg beige
frame .filelist.bbar	-bg beige

pack .filelist.listwin -side top -padx 20 -pady 7 -expand true -fill both
pack .filelist.textent -side top -padx 20 -pady 7 -fill x
pack .filelist.bbar -side bottom -padx 20 -pady 7 -fill x

simple .filelist.listwin.win -bg white
simple .filelist.listwin.sb -width 13 -bg beige

grid .filelist.listwin.win -row 0 -column 0 -sticky news -padx 1 -pady 1
grid .filelist.listwin.sb -row 0 -column 1 -sticky ns -padx 1 -pady 1

grid columnconfigure .filelist.listwin 0 -weight 1 -minsize 100
grid rowconfigure .filelist.listwin 0 -weight 1 -minsize 100

frame .filelist.textent.title -bg beige
pack .filelist.textent.title -side top -fill x

label .filelist.textent.title.field -text "Select file to load:" -bg beige
label .filelist.textent.title.chklabel -text "Filter" -bg beige
checkbutton .filelist.textent.title.filter -bg beige -variable XCOps(filter) \
   -command {event generate .filelist.listwin.win <ButtonPress> -button 3 ; \
	event generate .filelist.listwin.win <ButtonRelease> -button 3}

entry .filelist.textent.txt -bg white -relief sunken -width 50

pack .filelist.textent.title.filter -side right
pack .filelist.textent.title.chklabel -side right
pack .filelist.textent.title.field -side left
pack .filelist.textent.txt -side bottom -fill x -expand true

button .filelist.bbar.okay -text Okay -bg beige
button .filelist.bbar.cancel -text Cancel -bg beige -command {wm withdraw .filelist}

pack .filelist.bbar.okay -side left -ipadx 10
pack .filelist.bbar.cancel -side right -ipadx 10

# Allow <return> to update or accept entry
bind .filelist.textent.txt <Return> \
	{event generate .filelist.listwin.win <ButtonPress> -button 2 ; \
	event generate .filelist.listwin.win <ButtonRelease> -button 2}

#--------------------------------------
# Create the output generating window
#--------------------------------------

# First, set the variables associated with toggle and radio buttons
set XCOps(autofit) 0
set XCOps(imultiple) 0
set XCOps(dmultiple) 1
set XCOps(library) "User Library"

toplevel .output -bg beige
wm withdraw .output

frame .output.title -bg beige
frame .output.textent -bg beige
frame .output.bbar -bg beige

pack .output.title -side top -padx 20 -pady 7 -fill x
pack .output.textent -side top -padx 20 -pady 7 -fill x
pack .output.bbar -side bottom -padx 20 -pady 7 -fill x

label .output.title.field -text "PostScript output properties (Page 1):" -bg tan
checkbutton .output.title.imulti -text "1 schematic" -bg beige \
	-variable XCOps(imultiple) \
	-command {xcircuit::dolinks ; if {$XCOps(imultiple) == 1} {.output.textent.txt1 \
	delete 0 end; .output.textent.but1 configure -text Apply; xcircuit::page \
	filename {}; focus .output.textent.txt1 ; xcircuit::dolinks }}
checkbutton .output.title.dmulti -text "0 subcircuits" -bg beige \
	-variable XCOps(dmultiple) \
	-command {xcircuit::dolinks ; .output.textent.txt1 \
	delete 0 end; .output.textent.but1 configure -text Apply; xcircuit::page \
	filename {}; focus .output.textent.txt1 ; xcircuit::dolinks }
pack .output.title.dmulti -side right -padx 5
pack .output.title.imulti -side right -padx 5

pack .output.title.field -side left

label .output.textent.lab1 -text "Filename:" -bg beige
label .output.textent.lab2 -text "Page label:" -bg beige
label .output.textent.lab3 -text "Scale:" -bg beige
label .output.textent.lab4 -text "Width:" -bg beige
label .output.textent.lab5 -text "Height:" -bg beige
label .output.textent.lab6 -text "Orientation:" -bg beige
label .output.textent.lab7 -text "Mode:" -bg beige

entry .output.textent.txt1 -bg white -relief sunken -width 20
entry .output.textent.txt2 -bg white -relief sunken -width 20
entry .output.textent.txt3 -bg white -relief sunken -width 20
entry .output.textent.txt4 -bg white -relief sunken -width 20
entry .output.textent.txt5 -bg white -relief sunken -width 20

menubutton .output.textent.buto -text Portrait -bg beige \
	-menu .output.textent.buto.orientmenu
menubutton .output.textent.butp -text "Embedded (EPS)" -bg beige \
	-menu .output.textent.butp.psmenu

checkbutton .output.textent.butf -text "Auto-fit" -bg beige \
	-variable XCOps(autofit) -onvalue true -offvalue false \
	-command {xcircuit::page fit $XCOps(autofit)}
frame .output.textent.txtf -bg beige
menubutton .output.textent.txtf.sizb -text "Sizes" -bg beige \
	-menu .output.textent.txtf.sizb.sizemenu
entry .output.textent.txtf.txtp -bg white -relief sunken -width 14

pack .output.textent.txtf.txtp -side left -fill y
pack .output.textent.txtf.sizb -side left

button .output.textent.but1 -text Apply -bg beige \
	-command {xcircuit::page filename [.output.textent.txt1 get]
	if {[llength [xcircuit::page label]] > 1} {
	   xcircuit::page label [.output.textent.txt1 get]};\
	.output.textent.but1 configure -text Okay}
button .output.textent.but2 -text Apply -bg beige \
	-command {xcircuit::page label [.output.textent.txt2 get];\
	.output.textent.but2 configure -text Okay}
button .output.textent.but3 -text Apply -bg beige \
	-command {xcircuit::page scale [.output.textent.txt3 get];\
	.output.textent.but3 configure -text Okay}
button .output.textent.but4 -text Apply -bg beige \
	-command {xcircuit::page width [.output.textent.txt4 get];\
	.output.textent.but4 configure -text Okay}
button .output.textent.but5 -text Apply -bg beige \
	-command {xcircuit::page height [.output.textent.txt5 get];\
	.output.textent.but5 configure -text Okay}
button .output.textent.but7 -text Apply -bg beige \
	-command {xcircuit::page size [.output.textent.txtf.txtp get];\
	.output.textent.but7 configure -text Okay}

bind .output.textent.txt1 <Return> {.output.textent.but1 invoke}
bind .output.textent.txt2 <Return> {.output.textent.but2 invoke}
bind .output.textent.txt3 <Return> {.output.textent.but3 invoke}
bind .output.textent.txt4 <Return> {.output.textent.but4 invoke}
bind .output.textent.txt5 <Return> {.output.textent.but5 invoke}

grid .output.textent.lab1 -row 0 -column 0 -sticky w
grid .output.textent.lab2 -row 1 -column 0 -sticky w
grid .output.textent.lab3 -row 2 -column 0 -sticky w
grid .output.textent.lab4 -row 3 -column 0 -sticky w
grid .output.textent.lab5 -row 4 -column 0 -sticky w
grid .output.textent.lab6 -row 5 -column 0 -sticky w
grid .output.textent.lab7 -row 6 -column 0 -sticky w

grid .output.textent.txt1 -row 0 -column 1 -columnspan 2 -sticky ew -padx 10
grid .output.textent.txt2 -row 1 -column 1 -columnspan 2 -sticky ew -padx 10
grid .output.textent.txt3 -row 2 -column 1 -columnspan 2 -sticky ew -padx 10
grid .output.textent.txt4 -row 3 -column 1 -columnspan 2 -sticky ew -padx 10
grid .output.textent.txt5 -row 4 -column 1 -columnspan 2 -sticky ew -padx 10
grid .output.textent.buto -row 5 -column 1 -sticky w -padx 10
grid .output.textent.butp -row 6 -column 1 -sticky w -padx 10

grid .output.textent.but1 -row 0 -column 3 -pady 5 -ipadx 10
grid .output.textent.but2 -row 1 -column 3 -pady 5 -ipadx 10
grid .output.textent.but3 -row 2 -column 3 -pady 5 -ipadx 10
grid .output.textent.but4 -row 3 -column 3 -pady 5 -ipadx 10
grid .output.textent.but5 -row 4 -column 3 -pady 5 -ipadx 10

grid columnconfigure .output.textent 2 -weight 1

button .output.bbar.okay -text Okay -bg beige -command {xcircuit::page save; \
  wm withdraw .output}
button .output.bbar.cancel -text Cancel -bg beige -command {wm withdraw .output}

# Setup simple choice menus for page type and orientation
# First, set the variables associated with the radio buttons. . . 
set XCOps(orient) 0
set XCOps(pstype) eps

set m [menu .output.textent.buto.orientmenu -tearoff 0]
$m add radio -label "Portrait" -variable XCOps(orient) -value 0 -command \
	{.output.textent.buto configure -text Portrait ; \
	xcircuit::page orientation $XCOps(orient)}
$m add radio -label "Landscape" -variable XCOps(orient) -value 90 -command \
	{.output.textent.buto configure -text Landscape ; \
	xcircuit::page orientation $XCOps(orient)}
set m [menu .output.textent.butp.psmenu -tearoff 0]
$m add radio -label "Embedded (EPS)" -variable XCOps(pstype) -value eps -command \
	{xcircuit::setpstype eps}
$m add radio -label "Full Page" -variable XCOps(pstype) -value full -command \
	{xcircuit::setpstype full}
pack .output.bbar.okay -side left -ipadx 10
pack .output.bbar.cancel -side right -ipadx 10

set m [menu .output.textent.txtf.sizb.sizemenu -tearoff 0]
$m add radio -label "Letter (ANSI A)" -variable XCOps(sheetsize) \
	-value letter -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "8.5 x 11.0 in"}
$m add radio -label "Legal" -variable XCOps(sheetsize) -value legal -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "8.5 x 14.0 in"}
$m add radio -label "Statement" -variable XCOps(sheetsize) -value statement \
	-command \
	{ xcircuit::coordstyle inches; xcircuit::page size "5.5 x 8.5 in"}
$m add radio -label "Tabloid (ANSI B)" -variable XCOps(sheetsize) \
	 -value tabloid -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "11.0 x 17.0 in"}
$m add radio -label "Ledger" -variable XCOps(sheetsize) -value ledger -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "17.0 x 11.0 in"}
$m add radio -label "Folio" -variable XCOps(sheetsize) -value folio -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "8.5 x 13.0 in"}
$m add radio -label "Quarto" -variable XCOps(sheetsize) -value quarto -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "8.472 x 10.833 in"}
$m add radio -label "10x14" -variable XCOps(sheetsize) -value tenfourteen -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "10.0 x 14.0 in"}
$m add radio -label "Executive" -variable XCOps(sheetsize) -value executive -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "7.5 x 10.0 in"}
$m add radio -label "ANSI C" -variable XCOps(sheetsize) -value ansic -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "17.0 x 22.0 in"}
$m add radio -label "ANSI D" -variable XCOps(sheetsize) -value ansid -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "22.0 x 34.0 in"}
$m add radio -label "ANSI E" -variable XCOps(sheetsize) -value ansie -command \
	{ xcircuit::coordstyle inches; xcircuit::page size "34.0 x 44.0 in"}
$m add radio -label "A3" -variable XCOps(sheetsize) -value a3 -command \
	{ xcircuit::coordstyle centimeters; xcircuit::page size "29.7 x 42.0 cm"}
$m add radio -label "A4" -variable XCOps(sheetsize) -value a4 -command \
	{ xcircuit::coordstyle centimeters; xcircuit::page size "21.0 x 29.7 cm"}
$m add radio -label "A5" -variable XCOps(sheetsize) -value a5 -command \
	{ xcircuit::coordstyle centimeters; xcircuit::page size "14.82 x 18.43 cm"}
$m add radio -label "B4" -variable XCOps(sheetsize) -value b4 -command \
	{ xcircuit::coordstyle centimeters; xcircuit::page size "25.7 x 36.4 cm"}
$m add radio -label "B5" -variable XCOps(sheetsize) -value b5 -command \
	{ xcircuit::coordstyle centimeters; xcircuit::page size "18.2 x 25.7 cm"}

#-----------------------------------------------------------------
# Clear the selection listbox.  Create it if it does not exist.
#-----------------------------------------------------------------

proc xcircuit::reset_select_listbox {} {
   global p_key
   if {[catch {wm state .select}]} {
      toplevel .select -bg beige

      label .select.title -text "Parameters" -bg beige
      label .select.keytitle -text "Key" -bg beige
      label .select.valtitle -text "Value" -bg beige

      listbox .select.keylist -bg white
      listbox .select.vallist -bg white

      button .select.dismiss -text "Dismiss" -bg beige \
		-command {wm withdraw .select}

      grid .select.title -row 0 -column 0 -columnspan 2 -sticky news
      grid .select.keytitle -row 1 -column 0 -sticky news
      grid .select.keylist -row 2 -column 0 -sticky news
      grid .select.valtitle -row 1 -column 1 -sticky news
      grid .select.vallist -row 2 -column 1 -sticky news
      grid .select.dismiss -row 3 -column 0 -columnspan 2 -sticky ns

      grid rowconfigure .select 2 -weight 1
      grid columnconfigure .select 0 -weight 1
      grid columnconfigure .select 1 -weight 2

      bind .select.keylist <ButtonRelease-1> {set p_key [.select.keylist get \
		[.select.keylist nearest %y]]}
      bind .select.vallist <ButtonRelease-1> {set p_key [.select.keylist get \
		[.select.keylist nearest %y]]}
      bind .select.keylist <ButtonRelease-3> {set p_key {}}
      bind .select.vallist <ButtonRelease-3> {set p_key {}}
   } else {
      while {[.select.keylist size] > 0} {.select.keylist delete 0}
      while {[.select.vallist size] > 0} {.select.vallist delete 0}
   }
}

#--------------------------------------
# Create the simple popup prompt window
#--------------------------------------

toplevel .dialog -bg beige
wm withdraw .dialog

frame .dialog.textent -bg beige
frame .dialog.bbar	-bg beige

pack .dialog.textent -side top -padx 20 -pady 7 -fill x
pack .dialog.bbar -side bottom -padx 20 -pady 7 -fill x

frame .dialog.textent.title -bg beige
entry .dialog.textent.txt -bg white -relief sunken -width 50

pack .dialog.textent.title -side top -fill x
pack .dialog.textent.txt -side bottom -fill x -expand true

label .dialog.textent.title.field -text "Select file to load:" -bg beige
pack .dialog.textent.title.field -side left

button .dialog.bbar.okay -text Okay -bg beige
button .dialog.bbar.cancel -text Cancel -bg beige -command {wm withdraw .dialog}

bind .dialog.textent.txt <Return> {.dialog.bbar.okay invoke}

pack .dialog.bbar.okay -side left -ipadx 10
pack .dialog.bbar.cancel -side right -ipadx 10

#--------------------------------------
# Create the query prompt window
#--------------------------------------

toplevel .query -bg beige
wm withdraw .query

frame .query.title -bg beige
frame .query.bbar	-bg beige

pack .query.title -side top -padx 20 -pady 7 -fill x
pack .query.bbar -side bottom -padx 20 -pady 7 -fill x

label .query.title.field -text "Select:" -bg beige
pack .query.title.field -side left

button .query.bbar.okay -text Okay -bg beige
button .query.bbar.cancel -text Cancel -bg beige -command {wm withdraw .query}

pack .query.bbar.okay -side left -ipadx 10
pack .query.bbar.cancel -side right -ipadx 10

#--------------------------------------------------------
# Generate all of the menu cascades
# Most commands reference XCircuit internal routines
#--------------------------------------------------------

# Supporting procedures

proc xcircuit::printstring {stringlist} {
   set p ""
   foreach i $stringlist {
      switch -- [lindex $i 0] {
	 Text {append p [lindex $i 1]}
	 Half -
	 Quarter {append p " "} 
      }
   }
   return $p
}

proc xcircuit::printjust {justif} {
   switch [expr {$justif & 3}] {
      0 {set p "left"}
      1 {set p "center"}
      3 {set p "right"}
   }
   switch [expr {$justif & 12}] {
      0 {append p " bottom"}
      4 {append p " middle"}
      12 {append p " top"}
   }
   return $p
}

proc xcircuit::promptmakeparam {{mode substring}} {
   if {[xcircuit::select] > 0} {
      .dialog.bbar.okay configure -command \
	 [subst {xcircuit::parameter make $mode \[.dialog.textent.txt get\];\
	 wm withdraw .dialog}]
      .dialog.textent.title.field configure -text "Enter name for parameter"
   } else {
      .dialog.bbar.okay configure -command \
	 [subst {xcircuit::parameter make $mode \
	 \[lindex \[.dialog.textent.txt get\] 0\] \
	 \[lindex \[.dialog.textent.txt get\] 1\]; \
	 wm withdraw .dialog}]
      .dialog.textent.title.field configure -text "Enter name and value for parameter"
   }
   .dialog.textent.txt delete 0 end
   xcircuit::popupdialog
}

# This procedure generates a new index number for list selection
# inside a parameter, using "regsub" and "subst" to replace the
# old index with the new one.  This procedure depends on the
# existance of the listbox widget ".paramlist.plist".

proc xcircuit::renewparam {key y args} {
   set newidx [.paramlist.plist nearest $y]
   set current [join [xcircuit::parameter get $key ${args} -verbatim]]
   regsub {(.*lindex +{.*} +)([0-9]+)(.*)} $current {\1$newidx\3} tmpkey
   set newkey [subst -nocommands -nobackslashes "$tmpkey"]
   xcircuit::parameter set $key $newkey $args
   wm withdraw .paramlist
}

# Prompt for a new value of a parameter.  Do some sophisticated checking
# for parameters that declare a list of possible options, and handle
# that situation separately.

proc xcircuit::promptchangeparam {key current args} {
  if {[xcircuit::parameter type $key -forward] == "expression"} {

     # Use regexp processing to find if there is some part of the expression
     # that chooses a single fixed value from a list.  If so, generate a
     # listbox to present the choices in the list.

     set current [join [xcircuit::parameter get $key ${args} -verbatim]]
     if {[regexp {.*lindex +{(.*)} +[0-9]+.*} $current qall sellist] > 0} {
	if {[catch {wm title .paramlist}]} {
	   toplevel .paramlist
	   listbox .paramlist.plist
	   pack .paramlist.plist
	} else {
	   wm deiconify .paramlist
	   .paramlist.plist delete 0 end
	}
	foreach item $sellist {
	   .paramlist.plist insert end $item
	}
	bind .paramlist.plist <ButtonRelease-1> "xcircuit::renewparam $key %y $args"
	wm deiconify .paramlist
	return
     }
  }
  .dialog.bbar.okay configure -command \
	[subst {xcircuit::parameter set $key \[.dialog.textent.txt get\] ${args};\
	  wm withdraw .dialog}]
  .dialog.textent.title.field configure -text "Enter new value for parameter $key:"
  .dialog.textent.txt delete 0 end
  .dialog.textent.txt insert 0 $current
  xcircuit::popupdialog
}

proc xcircuit::promptselectparam {{mode {substring numeric expression}}} {
   global p_key
   set p_key {}
   set dlist {}

   foreach i $mode {
      set dlist [concat $dlist [parameter get $i]]
   }

   xcircuit::reset_select_listbox
   if {[llength $dlist] > 0} {
      if {[llength $dlist] == 1} {
	 set p_key [lindex [lindex $dlist 0] 0]
      } else {
	 if {[catch {set oname [xcircuit::object name]}]} {
	    .select.title configure -text "Parameters"
	 } else {
	    .select.title configure -text "Parameters of $oname"
	 }
         foreach i $dlist {
	    set p_name [lindex $i 0]
	    set p_val [lindex $i 1]
            .select.keylist insert end $p_name
	    switch -- [xcircuit::parameter type $p_name] {
	       "substring" {
	          .select.vallist insert end [xcircuit::printstring $p_val]
	       }
	       "justification" {
	          .select.vallist insert end [xcircuit::printjust $p_val]
	       }
	       default {
	          .select.vallist insert end $p_val
               }
	    }
         }
	 wm deiconify .select
	 raise .select
         tkwait variable p_key
	 .select.keylist delete 0 end
	 .select.vallist delete 0 end
	 wm withdraw .select
      }
   }
   return $p_key
}

proc xcircuit::prompteditparams { {mode "none"} } {
   xcircuit::reset_select_listbox
   if {$mode == "none"} {
      set dlist [xcircuit::parameter get -forward]
   } else {
      set dlist {}
      foreach i $mode {
         set dlist [concat $dlist [parameter get $i -forward]]
      }
   }

   bind .select.vallist <ButtonRelease-1> {
		set kidx [.select.keylist nearest %y]; \
		xcircuit::promptchangeparam \
		[.select.keylist get $kidx] [.select.vallist get $kidx] \
		-forward}

   if {[llength $dlist] > 0} {
      if {[catch {set oname [xcircuit::object name]}]} {
	 .select.title configure -text "Parameters"
      } else {
	 .select.title configure -text "Parameters of $oname"
      }
      foreach i $dlist {
	 set p_name [lindex $i 0]
	 set p_val [lindex $i 1]
         .select.keylist insert end $p_name
	 switch -- [xcircuit::parameter type $p_name -forward] {
	    "substring" {
	       .select.vallist insert end [xcircuit::printstring $p_val]
	    }
	    "justification" {
	       .select.vallist insert end [xcircuit::printjust $p_val]
	    }
	    default {
	       .select.vallist insert end $p_val
            }
	 }
      }
      wm deiconify .select
      raise .select
   }
}

proc xcircuit::promptmakesymbol {{name ""}} {
  global XCOps
  .dialog.bbar.okay configure -command \
	  {if {[string first "Page " [page label]] >= 0} { \
	  page label [.dialog.textent.txt get]}; \
	  xcircuit::symbol make [.dialog.textent.txt get] $XCOps(library); \
	  wm withdraw .dialog}
  .dialog.textent.title.field configure -text "Enter name for new object:"
  .dialog.textent.txt delete 0 end
  .dialog.textent.txt insert 0 $name
  xcircuit::popupdialog
  xcircuit::addliblist .dialog "Place in: "
}

proc xcircuit::promptelementsize {} {
   if {![catch {set cscale [xcircuit::element [select get] scale]}]} {
      .dialog.bbar.okay configure -command \
	  {xcircuit::element scale [.dialog.textent.txt get]; \
	  wm withdraw .dialog}
      .dialog.textent.title.field configure -text "Enter element scale:"
      .dialog.textent.txt delete 0 end
      .dialog.textent.txt insert 0 $cscale
      xcircuit::popupdialog
   }
}

proc xcircuit::promptborderwidth {} {
   global tcl_precision
   .dialog.textent.txt delete 0 end
   set savep $tcl_precision
   set tcl_precision 3
   set elist [xcircuit::select get]
   if {[llength $elist] == 0} {
      .dialog.bbar.okay configure -command \
	   {xcircuit::border set [.dialog.textent.txt get]; \
	   wm withdraw .dialog}
      .dialog.textent.title.field configure -text "Enter default linewidth scale:"
      .dialog.textent.txt insert 0 [xcircuit::border get]
   } else {
      .dialog.bbar.okay configure -command \
	   {xcircuit::border set [.dialog.textent.txt get]; \
	   wm withdraw .dialog}
      .dialog.textent.title.field configure -text "Enter element linewidth:"
      .dialog.textent.txt insert 0 [lindex [xcircuit::border get] 0]
   }
   set tcl_precision $savep
   xcircuit::popupdialog
}

proc xcircuit::promptlinewidth {} {
   global tcl_precision
   .dialog.bbar.okay configure -command \
	{xcircuit::config linewidth [.dialog.textent.txt get]; \
	 wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Enter page linewidth scaling:"
   .dialog.textent.txt delete 0 end
   set savep $tcl_precision
   set tcl_precision 3
   .dialog.textent.txt insert 0 [xcircuit::config linewidth]
   set tcl_precision $savep
   xcircuit::popupdialog
}

proc xcircuit::promptdrawingscale {} {
   global tcl_precision
   .dialog.bbar.okay configure -command \
	{xcircuit::config drawingscale [.dialog.textent.txt get]; wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Enter drawing scale:"
   .dialog.textent.txt delete 0 end
   set savep $tcl_precision
   set tcl_precision 3
   .dialog.textent.txt insert 0 [xcircuit::config drawingscale]
   set tcl_precision $savep
   xcircuit::popupdialog
}

proc xcircuit::promptgridspace {} {
   global tcl_precision
   .dialog.bbar.okay configure -command \
	{xcircuit::config grid spacing [.dialog.textent.txt get]; wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Enter grid spacing:"
   .dialog.textent.txt delete 0 end
   set savep $tcl_precision
   set tcl_precision 3
   .dialog.textent.txt insert 0 [xcircuit::config grid space]
   set tcl_precision $savep
   xcircuit::popupdialog
}

proc xcircuit::promptsnapspace {} {
   global tcl_precision
   .dialog.bbar.okay configure -command \
	{xcircuit::config snap spacing [.dialog.textent.txt get]; wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Enter snap spacing:"
   .dialog.textent.txt delete 0 end
   set savep $tcl_precision
   set tcl_precision 3
   .dialog.textent.txt insert 0 [xcircuit::config snap space]
   set tcl_precision $savep
   xcircuit::popupdialog
}

proc xcircuit::promptmakeobject {} {
   global XCOps
   if {[xcircuit::select] > 0} {
      .dialog.bbar.okay configure -command \
	  {xcircuit::object make [.dialog.textent.txt get] $XCOps(library); \
	  wm withdraw .dialog}
      .dialog.textent.title.field configure -text "Enter name for new object"
      .dialog.textent.txt delete 0 end
      xcircuit::popupdialog
      xcircuit::addliblist .dialog "Place in: "
   }
}

proc xcircuit::promptloadlibrary {} {
   global XCOps

   .filelist.bbar.okay configure -command \
	{xcircuit::library $XCOps(library) load [.filelist.textent.txt get]; \
	wm withdraw .filelist}
   .filelist.listwin.win configure -data "lps"
   .filelist.textent.title.field configure -text "Select library file to load:"
   .filelist.textent.txt delete 0 end
   xcircuit::popupfilelist
   xcircuit::addliblist .filelist "Load to which library page: " {} true
   set XCOps(library) "User Library"
}

proc xcircuit::promptsavelib { libno } {
   global XCOps

   .dialog.bbar.okay configure -command \
	{xcircuit::library $XCOps(library) save [.dialog.textent.txt get]; \
	 wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Enter filename to save library as:"
   .dialog.textent.txt delete 0 end
   .dialog.textent.txt insert 0 [library $libno filename]
   xcircuit::popupdialog
   xcircuit::addliblist .dialog "Save which library: " {} true
   set XCOps(library) [xcircuit::library $libno]
   .dialog.libself.libselect configure -text $XCOps(library)
}

proc xcircuit::promptaddlibrary {} {
   .dialog.bbar.okay configure -command \
	{xcircuit::library make [.dialog.textent.txt get]; wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Name of new library page:"
   .dialog.textent.txt delete 0 end
   xcircuit::popupdialog
}

proc xcircuit::promptloadfile {} {
   .filelist.bbar.okay configure -command \
	{xcircuit::page load [.filelist.textent.txt get] -replace $XCOps(library); \
	 wm withdraw .filelist}
   .filelist.listwin.win configure -data "ps"
   .filelist.textent.title.field configure -text "Select file to load:"
   .filelist.textent.txt delete 0 end
   xcircuit::popupfilelist
   xcircuit::addliblist .filelist "Replace from: " {all none}
}

proc xcircuit::promptimportspice {} {
   .filelist.bbar.okay configure -command \
	{xcircuit::page import spice \
	[.filelist.textent.txt get]; wm withdraw .filelist}
   .filelist.listwin.win configure -data "spice"
   .filelist.textent.title.field configure -text "Select SPICE file to import:"
   .filelist.textent.txt delete 0 end
   xcircuit::popupfilelist
}

proc xcircuit::promptimportfile {} {
   .filelist.bbar.okay configure -command \
	{xcircuit::page import xcircuit \
	[.filelist.textent.txt get]; wm withdraw .filelist}
   .filelist.listwin.win configure -data "ps"
   .filelist.textent.title.field configure -text "Select file to import:"
   xcircuit::popupfilelist
}

proc xcircuit::promptimportbackground {} {
   .filelist.bbar.okay configure -command \
	{xcircuit::page import background \
	[.filelist.textent.txt get]; wm withdraw .filelist}
   .filelist.listwin.win configure -data "ps"
   .filelist.textent.title.field configure -text "Select file to use as background:"
   .filelist.textent.txt delete 0 end
   xcircuit::popupfilelist
}

proc xcircuit::promptimportgraphic {} {
   .filelist.bbar.okay configure -command \
	{xcircuit::graphic make [.filelist.textent.txt get] {0 0} 1;
	 refresh; wm withdraw .filelist}
   .filelist.listwin.win configure -data "pnm"
   .filelist.textent.title.field configure -text "Select graphic image file:"
   .filelist.textent.txt delete 0 end
   xcircuit::popupfilelist
}

proc xcircuit::promptexecscript {} {
   .filelist.bbar.okay configure -command \
	{source [.filelist.textent.txt get]; wm withdraw .filelist}
   .filelist.listwin.win configure -data "tcl"
   .filelist.textent.title.field configure -text "Select script to execute:"
   xcircuit::popupfilelist
}

proc xcircuit::prompttextsize {} {
   global tcl_precision
   .dialog.bbar.okay configure -command \
	{xcircuit::label scale [.dialog.textent.txt get]; wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Enter text scale:"
   .dialog.textent.txt delete 0 end
   set savep $tcl_precision
   set tcl_precision 3
   .dialog.textent.txt insert 0 [xcircuit::label scale]
   set tcl_precision $savep
   xcircuit::popupdialog
}

# add a library list widget to a dialog box

proc xcircuit::addliblist {w {prompt "Target: "} {endlist {}} {update false}} {
   global XCOps

   xcircuit::removeliblist ${w}

   frame ${w}.libself
   label ${w}.libself.title -text $prompt -bg beige

   set liblist [library directory list]
   foreach j $endlist { lappend liblist $j }

   menubutton ${w}.libself.libselect -menu ${w}.libself.libselect.menu -relief groove
   menu ${w}.libself.libselect.menu -tearoff 0
   if {$update} {
      foreach j $liblist {
         ${w}.libself.libselect.menu add \
	   radio -label $j -variable XCOps(library) -value \
	   $j -command "${w}.libself.libselect configure -text {$j} ; \
	   ${w}.textent.txt delete 0 end ; \
	   ${w}.textent.txt insert 0 [library $j filename]"
      }
   } else {
      foreach j $liblist {
         ${w}.libself.libselect.menu add \
	   radio -label $j -variable XCOps(library) -value \
	   $j -command "${w}.libself.libselect configure -text {$j}"
      }
   }
   ${w}.libself.libselect configure -text $j
   set XCOps(library) $j

   pack ${w}.libself.title -side left
   pack ${w}.libself.libselect -side left
   pack ${w}.libself -side top -anchor w -padx 20
}

proc xcircuit::removeliblist {w} {
   global XCOps

   catch {
      pack forget ${w}.libself
      destroy ${w}.libself
   }
   set XCOps(library) "User Library"
}

# newcolorbutton is called internally to xcircuit---don't mess with it!

proc xcircuit::newcolorbutton {r g b idx} {
   global XCIRCUIT_LIB_DIR
   set colorrgb [format "#%04X%04X%04X" $r $g $b]
   image create bitmap img_col$idx -foreground $colorrgb -file \
		${XCIRCUIT_LIB_DIR}/pixmaps/solid.xbm
   .xcircuit.menubar.optionsbutton.optionsmenu.elementsmenu.colormenu \
	add radio -image img_col$idx -activebackground $colorrgb \
	-variable XCOps(colorval) -value $idx -command "xcircuit::color set $idx"
}

proc xcircuit::picknewcolor {} {
   set colorrgb [tkColorDialog]
   xcircuit::color add $colorrgb
}

proc xcircuit::newencodingbutton {encodingname} {
   if {[catch {.xcircuit.menubar.textbutton.textmenu.encodingmenu \
		index $encodingname} result]} {
      .xcircuit.menubar.textbutton.textmenu.encodingmenu add radio -label \
	  	$encodingname -command "xcircuit::label encoding $encodingname" \
		-variable XCOps(fontencoding) -value $encodingname
   }
}

proc xcircuit::newfontbutton {familyname} {
   if {[catch {.xcircuit.menubar.textbutton.textmenu.fontmenu \
		index $familyname} result]} {
      .xcircuit.menubar.textbutton.textmenu.fontmenu add radio -label \
	  	$familyname -command "xcircuit::label family $familyname" \
		-variable XCOps(fontfamily) -value $familyname
   }
}

proc xcircuit::newlibrarybutton {libname} {
   if {[catch {.xcircuit.menubar.windowbutton.windowmenu.librarymenu \
		index $libname} result]} {
      set libidx [.xcircuit.menubar.windowbutton.windowmenu.librarymenu \
		index end]
      if {$libidx <= 1} {set libidx [expr $libidx + 1]}
      .xcircuit.menubar.windowbutton.windowmenu.librarymenu insert $libidx \
		command -label $libname -command "xcircuit::library \"$libname\" goto"
   }
}

proc xcircuit::newpagebutton {pagename {pageno 0}} {
   if {[catch {.xcircuit.menubar.windowbutton.windowmenu.pagemenu \
		index $pagename} result]} {
      set target $pagename
      if {$pageno > 0} { set target $pageno }
      .xcircuit.menubar.windowbutton.windowmenu.pagemenu add command -label \
	  	$pagename -command "xcircuit::page \"$target\" goto"
   }
}

proc xcircuit::renamelib {libno libname} {
   set target [expr $libno + 1]
   .xcircuit.menubar.windowbutton.windowmenu.librarymenu entryconfigure \
		$target -label $libname -command "xcircuit::library \"$libname\" goto"
}

proc xcircuit::renamepage {pageno pagename} {
   set target [expr $pageno + 1]
   .xcircuit.menubar.windowbutton.windowmenu.pagemenu entryconfigure \
		$target -label $pagename -command "xcircuit::page \"$pagename\" goto"
}

proc xcircuit::promptnewfont {} {
   .dialog.bbar.okay configure -command \
	{xcircuit::loadfont [.dialog.textent.txt get]; wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Enter font name:"
   .dialog.textent.txt delete 0 end
   xcircuit::popupdialog
}

proc xcircuit::promptkern {} {
   .dialog.bbar.okay configure -command \
	{xcircuit::label insert kern [.dialog.textent.txt get]; wm withdraw .dialog}
   .dialog.textent.title.field configure -text "Enter kern amount:"
   .dialog.textent.txt delete 0 end
   xcircuit::popupdialog
}

proc xcircuit::xschema {value} {
   switch -- $value {
      true -
      enable {
	 pack forget .xcircuit.menubar.message
	 pack .xcircuit.menubar.netlistbutton -side left -padx 2 -ipadx 10 -pady 2
	 pack .xcircuit.menubar.message -side top -fill x -padx 2 -ipady 3 -pady 2
	 pack forget .xcircuit.infobar.message1
	 pack forget .xcircuit.infobar.message2
	 pack .xcircuit.infobar.symb .xcircuit.infobar.schem \
        	.xcircuit.infobar.message1 -side left -padx 2 -ipadx 6
	 pack .xcircuit.infobar.message2 -side bottom -padx 2 -ipadx 6 -fill x
	 set midx [.xcircuit.menubar.optionsbutton.optionsmenu \
		index "Enable XSchema"]
	 .xcircuit.menubar.optionsbutton.optionsmenu entryconfigure $midx \
		-command {xcircuit::xschema disable} -label \
		"Disable XSchema"
      }
      false -
      disable {
	 pack forget .xcircuit.menubar.netlistbutton
	 pack forget .xcircuit.infobar.symb
	 pack forget .xcircuit.infobar.schem
	 set midx [.xcircuit.menubar.optionsbutton.optionsmenu \
		index "Disable XSchema"]
	 .xcircuit.menubar.optionsbutton.optionsmenu entryconfigure $midx \
		-command {xcircuit::xschema enable} -label \
		"Enable XSchema"
      }
   }
}

set XCOps(button1) Wire;
set XCOps(tools) [list pn w b a s t mv cp e d2 cw ccw fx fy pu2 po2 mk pz uj \
	co bd fi pm li yp pl z4 z5 pa i]

proc xcircuit::modebutton {widget} {
   global XCOps
   for {set i 0} {$i < [llength $XCOps(tools)]} {incr i 1} {
      set bname [lindex $XCOps(tools) $i]
      .xcircuit.mainframe.toolbar.b${bname} configure -relief raised \
		-highlightbackground gray90 -background gray90
   }
   $widget configure -relief solid -highlightbackground green3 -background green3
   if {$XCOps(button1) == "Rotate"} {
      .xcircuit.infobar.mode configure -text "$XCOps(button1) $XCOps(rotateamount) Mode"
   } else {
      .xcircuit.infobar.mode configure -text "$XCOps(button1) Mode"
   }
}

proc xcircuit::createtoolbar {} {
   global XCIRCUIT_LIB_DIR
   global XCOps
   global tcl_platform
   set tooltips [list "pan window" "draw wire" "draw box" \
	"draw arc" "draw spline" "enter text" \
	"move element" "copy element" "edit element" "delete element" \
	"rotate 15 degrees clockwise" "rotate 15 degrees counterclockwise" \
	"flip horizontal" "flip vertical" "push (edit object)" \
	"pop (return from object edit)" "make an object from selection" \
	"join elements into polygon or path" "separate path into elements" \
	"set color" "set border and line properties" "set fill properties" \
	"parameterize properties" "go to next library" "go to library directory" \
	"go to page directory" "zoom in" "zoom out" \
	"parameter selection" "pop up help window"]	
   set toolactions [list \
	{bindkey Button1 $XCOps(button1) forget; bindkey Button1 Pan 6; \
		set XCOps(button1) Pan; xcircuit::modebutton %W; cursor hand} \
	{bindkey Button1 $XCOps(button1) forget; bindkey Button1 Wire; \
		set XCOps(button1) Wire; xcircuit::modebutton %W; cursor cross} \
	{bindkey Button1 $XCOps(button1) forget; bindkey Button1 Box; \
		set XCOps(button1) Box; xcircuit::modebutton %W; cursor cross} \
	{bindkey Button1 $XCOps(button1) forget; bindkey Button1 Arc; \
		set XCOps(button1) Arc; xcircuit::modebutton %W; cursor circle} \
	{bindkey Button1 $XCOps(button1) forget; bindkey Button1 Spline; \
		set XCOps(button1) Spline; xcircuit::modebutton %W; cursor arrow} \
	{bindkey Button1 $XCOps(button1) forget; bindkey Button1 $XCOps(labeltype); \
		set XCOps(button1) $XCOps(labeltype); xcircuit::modebutton %W; \
		.xcircuit.mainframe.toolbar.bt configure -image $XCOps(labelimage); \
		cursor text} \
	{if {[select]} {move selected} else {bindkey Button1 $XCOps(button1) forget; \
		bindkey Button1 Move; set XCOps(button1) Move; xcircuit::modebutton %W; \
		cursor arrow}} \
	{if {[select]} {copy selected} else {bindkey Button1 $XCOps(button1) forget; \
		bindkey Button1 Copy; set XCOps(button1) Copy; xcircuit::modebutton %W; \
		cursor copy}} \
	{if {[select] == 1} {edit selected} else {bindkey Button1 $XCOps(button1) \
		forget; bindkey Button1 Edit; set XCOps(button1) Edit; \
		xcircuit::modebutton %W; cursor edit}} \
	{if {[select]} {delete selected} else {bindkey Button1 $XCOps(button1) forget; \
		bindkey Button1 Delete; set XCOps(button1) Delete; \
		xcircuit::modebutton %W; cursor scissors}} \
	{if {[select] == 1} {rotate $XCOps(rotateamount)} else {bindkey Button1 \
		$XCOps(button1) forget; bindkey Button1 Rotate \
		$XCOps(rotateamount); set XCOps(button1) Rotate; \
		xcircuit::modebutton %W; cursor rotate}} \
	{if {[select] == 1} {rotate -$XCOps(rotateamount)} else {bindkey Button1 \
		$XCOps(button1) forget; bindkey Button1 Rotate \
		-$XCOps(rotateamount); set XCOps(button1) Rotate; \
		xcircuit::modebutton %W; cursor rotate}} \
	{if {[select] == 1} {flip horizontal} else {bindkey Button1 $XCOps(button1) \
		forget; bindkey Button1 "Flip X"; set XCOps(button1) "Flip X"; \
		xcircuit::modebutton %W; cursor rotate}} \
	{if {[select] == 1} {flip vertical} else {bindkey Button1 $XCOps(button1) \
		forget; bindkey Button1 "Flip Y"; set XCOps(button1) "Flip Y"; \
		xcircuit::modebutton %W; cursor rotate}} \
	{if {[select] == 1} {push selected} else {bindkey Button1 $XCOps(button1) \
		forget; bindkey Button1 Push; set XCOps(button1) Push; \
		xcircuit::modebutton %W; cursor question}} \
	{pop} \
	{if {[select]} {xcircuit::promptmakeobject} else {bindkey Button1 \
		$XCOps(button1) forget; bindkey Button1 "Select Save"; \
		set XCOps(button1) "Select Save"; xcircuit::modebutton %W; \
		cursor question}} \
	{if {[select]} {path join selected} else {bindkey Button1 $XCOps(button1) \
		forget; bindkey Button1 Join; set XCOps(button1) Join; \
		xcircuit::modebutton %W; cursor arrow}} \
	{if {[select] == 1} {path unjoin selected} else {bindkey Button1 \
		$XCOps(button1) forget; bindkey Button1 Unjoin; \
		set XCOps(button1) Unjoin; xcircuit::modebutton %W; cursor arrow}} \
	{tk_popup .colormenu [expr {[winfo rootx \
		.xcircuit.mainframe.toolbar.bco] \
		- [winfo width .colormenu]}] \
		[expr {[winfo rooty .xcircuit.mainframe.toolbar.bco] \
		- [winfo height .colormenu] / 2}] } \
	{tk_popup .bordermenu [expr {[winfo rootx \
		.xcircuit.mainframe.toolbar.bbd] \
		- [winfo width .bordermenu]}] \
		[expr {[winfo rooty .xcircuit.mainframe.toolbar.bbd] \
		- [winfo height .bordermenu] / 2}] } \
	{tk_popup .fillmenu [expr {[winfo rootx \
		.xcircuit.mainframe.toolbar.bfi] \
		- [winfo width .fillmenu]}] \
		[expr {[winfo rooty .xcircuit.mainframe.toolbar.bfi] \
		- [winfo height .fillmenu] / 2}] } \
	{tk_popup .parammenu [expr {[winfo rootx \
		.xcircuit.mainframe.toolbar.bpm] \
		- [winfo width .parammenu]}] \
		[expr {[winfo rooty .xcircuit.mainframe.toolbar.bpm] \
		- [winfo height .parammenu] / 2}] } \
	{library next} \
	{library directory} {page directory} \
	{zoom 1.5; refresh} {zoom [expr {1 / 1.5}]; refresh} \
	{xcircuit::prompteditparams {substring numeric expression}} \
	{xcircuit::helpwindow} ]

   for {set i 0} {$i < [llength $XCOps(tools)]} {incr i 1} {
      set bname [lindex $XCOps(tools) $i]
      set btip [lindex $tooltips $i]
      image create photo img_${bname} -file ${XCIRCUIT_LIB_DIR}/pixmaps/${bname}.gif
      regsub -all -- %W [lindex $toolactions $i] \
		.xcircuit.mainframe.toolbar.b${bname} bcmd
      button .xcircuit.mainframe.toolbar.b${bname} -image img_${bname} -command \
		"$bcmd"
      bind .xcircuit.mainframe.toolbar.b${bname} <Enter> \
		[subst {.xcircuit.infobar.message2 configure -text "$btip"}]
      bind .xcircuit.mainframe.toolbar.b${bname} <Leave> \
		[subst {.xcircuit.infobar.message2 configure -text ""}]
   }

   # alternate label type images (info, global, and pin labels)
   image create photo img_ti -file ${XCIRCUIT_LIB_DIR}/pixmaps/ti.gif
   image create photo img_tg -file ${XCIRCUIT_LIB_DIR}/pixmaps/tg.gif
   image create photo img_tp -file ${XCIRCUIT_LIB_DIR}/pixmaps/tp.gif
 
   # pack the first button so we can query its height for arrangement.
   # this assumes that the height of each button is the same!
   set bname [lindex $XCOps(tools) 0]
   place .xcircuit.mainframe.toolbar.b${bname} -x 0 -y 0
   update idletasks
}

proc xcircuit::arrangetoolbar {} {
   global XCOps

   set numtools [llength $XCOps(tools)]
   for {set i 0} {$i < $numtools} {incr i 1} {
      set bname [lindex $XCOps(tools) $i]
      place forget .xcircuit.mainframe.toolbar.b${bname}
   }
   set bname [lindex $XCOps(tools) 0]
   set bheight [winfo height .xcircuit.mainframe.toolbar.b${bname}]
   set bwidth [winfo width .xcircuit.mainframe.toolbar.b${bname}]
   set wheight [winfo height .xcircuit.mainframe]
   set nrows [expr {$wheight / $bheight}]
   .xcircuit.mainframe.toolbar configure -width [expr {$bwidth}]
   set j 0
   set k 0
   for {set i 0} {$i < [llength $XCOps(tools)]} {incr i; incr j} {
      if {$j == $nrows} {
	 set j 0
	 incr k
	 .xcircuit.mainframe.toolbar configure -width [expr {($k + 1) * $bwidth}]
      }
      set bname [lindex $XCOps(tools) $i]
      place .xcircuit.mainframe.toolbar.b${bname} \
		-x [expr {$k * $bwidth}] \
		-y [expr {$j * $bheight}]
   }
}

proc xcircuit::toolbar {value} {
   switch -- $value {
      true -
      enable {
	 pack forget .xcircuit.mainframe.mainarea
	 pack .xcircuit.mainframe.toolbar -side right -fill y -padx 2
	 pack .xcircuit.mainframe.mainarea -expand true -fill both
	 set midx [.xcircuit.menubar.optionsbutton.optionsmenu \
		index "Enable Toolbar"]
	 .xcircuit.menubar.optionsbutton.optionsmenu entryconfigure $midx \
		-command {xcircuit::toolbar disable} -label \
		"Disable Toolbar"
      }
      false -
      disable {
	 pack forget .xcircuit.mainframe.toolbar
	 set midx [.xcircuit.menubar.optionsbutton.optionsmenu \
		index "Disable Toolbar"]
	 .xcircuit.menubar.optionsbutton.optionsmenu entryconfigure $midx \
		-command {xcircuit::toolbar enable} -label \
		"Enable Toolbar"
      }
   }
}

# First, set the variables associated with toggle and radio buttons
set XCOps(colorval) inherit
set XCOps(jhoriz) left
set XCOps(jvert) bottom
set XCOps(linestyle) solid
set XCOps(fillamount) 0
set XCOps(opaque) false
set XCOps(polyedittype) manhattan
set XCOps(showgrid) true
set XCOps(showsnap) true
set XCOps(showaxes) true
set XCOps(showbbox) false
set XCOps(fontfamily) Helvetica
set XCOps(fontstyle) normal
set XCOps(fontencoding) Standard
set XCOps(fontlining) normal
set XCOps(fontscript) normal
set XCOps(gridstyle) "fractional inches"
set XCOps(flipinvariant) true
set XCOps(pinvisible) false
set XCOps(latexmode) false
set XCOps(colorscheme) normal
set XCOps(editinplace) true
set XCOps(pinpositions) invisible
set XCOps(centerobject) true
set XCOps(manhattandraw) false
set XCOps(polyclosed) closed
set XCOps(endcaps) round
set XCOps(bboxtype) false
set XCOps(substringparam) false
set XCOps(positionparam) false
set XCOps(numericparam) false
set XCOps(expressparam) false
set XCOps(styleparam) false
set XCOps(justparam) false
set XCOps(startparam) false
set XCOps(endparam) false
set XCOps(radiusparam) false
set XCOps(minorparam) false
set XCOps(rotationparam) false
set XCOps(scaleparam) false
set XCOps(linewidthparam) false
set XCOps(colorparam) false
set XCOps(sel_lab) true
set XCOps(sel_obj) true
set XCOps(sel_poly) true
set XCOps(sel_arc) true
set XCOps(sel_spline) true
set XCOps(sel_path) true
set XCOps(sheetsize) letter
set XCOps(spiceend) true
set XCOps(forcenets) true
set XCOps(labeltype) Text
set XCOps(labelimage) img_t
set XCOps(rotateamount) 15

set m [menu .xcircuit.menubar.filebutton.filemenu -tearoff 0]
$m add command -label "Read XCircuit File" -command {xcircuit::promptloadfile}
$m add command -label "Write XCircuit PS" -command {xcircuit::promptsavepage}
$m add separator
$m add command -label "Import XCircuit PS" -command {xcircuit::promptimportfile}
$m add command -label "Import background PS" -command {xcircuit::promptimportbackground}
$m add command -label "Import graphic image (PPM)" -command \
	{xcircuit::promptimportgraphic}
# If the "matgen.tcl" script exists, source it
if {![catch {source $XCIRCUIT_LIB_DIR/matgen.tcl}]} {
   $m add command -label "Import Matlab PS" -command {xcircuit::promptimportmatlab}
}
$m add command -label "Execute Script" -command {xcircuit::promptexecscript}
if {[file tail [info nameofexecutable]] != "xcircexec"} {
   $m add command -label "Tcl Console" -command {xcircuit::raiseconsole}
}
$m add separator
$m add command -label "New Library Page" -command {xcircuit::promptaddlibrary}
$m add command -label "Load Library File" -command {xcircuit::promptloadlibrary}
$m add command -label "Save Library Page" -command {if {[catch xcircuit::library]} \
	{xcircuit::promptsavelib [xcircuit::library "User Library"]} \
	{xcircuit::promptsavelib [xcircuit::library]}}
# If the "library.tcl" script exists, source it
if {![catch {source $XCIRCUIT_LIB_DIR/library.tcl}]} {
   $m add command -label "Library Manager" -command {xcircuit::raisemanager}
}
$m add separator
$m add command -label "Clear Page" -command {xcircuit::page reset}
$m add separator
$m add command -label "Quit" -command {quit}

set m [menu .xcircuit.menubar.editbutton.editmenu -tearoff 0]
$m add command -label "Undo" -command {undo}
$m add command -label "Redo" -command {redo}
$m add separator
$m add command -label "Delete" -command \
	{.xcircuit.mainframe.toolbar.bd2 invoke}
$m add command -label "Copy" -command \
	{.xcircuit.mainframe.toolbar.bcp invoke}
$m add command -label "Move" -command \
	{.xcircuit.mainframe.toolbar.bmv invoke}
$m add command -label "Edit" -command \
	{.xcircuit.mainframe.toolbar.be invoke}
$m add cascade -label "Rotate/Flip" -menu $m.rotmenu
$m add command -label "Deselect" -command {deselect}
$m add cascade -label "Select Filter" -menu $m.selmenu
$m add command -label "Push Selected" -command \
	{.xcircuit.mainframe.toolbar.pu2 invoke}
$m add command -label "Pop Hierarchy" -command {pop}
$m add separator
$m add command -label "Make User Object" -command \
	{.xcircuit.mainframe.toolbar.bmk invoke}
$m add command -label "Make Arc" -command \
	{.xcircuit.mainframe.toolbar.ba invoke}
$m add command -label "Make Box" -command \
	{.xcircuit.mainframe.toolbar.bb invoke}
$m add command -label "Make Spline" -command \
	{.xcircuit.mainframe.toolbar.bs invoke}
$m add command -label "Make Wire" -command \
	{.xcircuit.mainframe.toolbar.bw invoke}
$m add command -label "Join" -command \
	{.xcircuit.mainframe.toolbar.bpz invoke}
$m add command -label "Unjoin" -command \
	{.xcircuit.mainframe.toolbar.buj invoke}

set m2 [menu $m.rotmenu -tearoff 0]
$m2 add command -label "Flip Horizontal" -command \
	{.xcircuit.mainframe.toolbar.bfx invoke}
$m2 add command -label "Flip Vertical" -command \
	{.xcircuit.mainframe.toolbar.bfy invoke}
$m2 add separator
$m2 add command -label "Rotate CW 90" -command \
	{set XCOps(rotateamount) 90; .xcircuit.mainframe.toolbar.bcw invoke}
$m2 add command -label "Rotate CW 45" -command \
	{set XCOps(rotateamount) 45; .xcircuit.mainframe.toolbar.bcw invoke}
$m2 add command -label "Rotate CW 30" -command \
	{set XCOps(rotateamount) 30; .xcircuit.mainframe.toolbar.bcw invoke}
$m2 add command -label "Rotate CW 15" -command \
	{set XCOps(rotateamount) 15; .xcircuit.mainframe.toolbar.bcw invoke}
$m2 add command -label "Rotate CW 5" -command \
	{set XCOps(rotateamount) 5; .xcircuit.mainframe.toolbar.bcw invoke}
$m2 add command -label "Rotate CW 1" -command \
	{set XCOps(rotateamount) 1; .xcircuit.mainframe.toolbar.bcw invoke}
$m2 add separator
$m2 add command -label "Rotate CCW 90" -command \
	{set XCOps(rotateamount) 90; .xcircuit.mainframe.toolbar.bccw invoke}
$m2 add command -label "Rotate CCW 45" -command \
	{set XCOps(rotateamount) 45; .xcircuit.mainframe.toolbar.bccw invoke}
$m2 add command -label "Rotate CCW 30" -command \
	{set XCOps(rotateamount) 30; .xcircuit.mainframe.toolbar.bccw invoke}
$m2 add command -label "Rotate CCW 15" -command \
	{set XCOps(rotateamount) 15; .xcircuit.mainframe.toolbar.bccw invoke}
$m2 add command -label "Rotate CCW 5" -command \
	{set XCOps(rotateamount) 5; .xcircuit.mainframe.toolbar.bccw invoke}
$m2 add command -label "Rotate CCW 1" -command \
	{set XCOps(rotateamount) 1; .xcircuit.mainframe.toolbar.bccw invoke}

set m2 [menu $m.selmenu -tearoff 0]
$m2 add command -label "Disable selection" -command {element select hide}
$m2 add command -label "Remove all disabled" -command {element select allow}
$m2 add separator
$m2 add check -label "Labels" -variable XCOps(sel_lab) -onvalue true -offvalue false \
	-command {xcircuit::config filter label $XCOps(sel_lab)}
$m2 add check -label "Objects" -variable XCOps(sel_obj) -onvalue true -offvalue false \
	-command {xcircuit::config filter instance $XCOps(sel_obj)}
$m2 add check -label "Polygons" -variable XCOps(sel_poly) -onvalue true -offvalue false \
	-command {xcircuit::config filter polygon $XCOps(sel_poly)}
$m2 add check -label "Arcs" -variable XCOps(sel_arc) -onvalue true -offvalue false \
	-command {xcircuit::config filter arc $XCOps(sel_arc)}
$m2 add check -label "Splines" -variable XCOps(sel_spline) -onvalue true -offvalue false \
	-command {xcircuit::config filter spline $XCOps(sel_spline)}
$m2 add check -label "Paths" -variable XCOps(sel_path) -onvalue true -offvalue false \
	-command {xcircuit::config filter path $XCOps(sel_path)}

set m [menu .xcircuit.menubar.textbutton.textmenu -tearoff 0]
$m add command -label "Text Size" -command {xcircuit::prompttextsize}
$m add cascade -label "Font" -menu $m.fontmenu
$m add cascade -label "Style" -menu $m.stylemenu
$m add cascade -label "Encoding" -menu $m.encodingmenu
$m add cascade -label "Insert" -menu $m.insertmenu
$m add cascade -label "Justification" -menu $m.justifymenu
$m add command -label "Parameterize" \
	-command {xcircuit::promptmakeparam}
$m add command -label "Unparameterize" \
	-command {xcircuit::parameter forget substring}
$m add separator
$m add check -label "LaTeX mode" -variable XCOps(latexmode) -onvalue true \
	-offvalue false -command {xcircuit::label latex $XCOps(latexmode)}
$m add separator
$m add command -label "Increment Number" -command \
	{xcircuit::textincrement [select get]; refresh}
$m add command -label "Decrement Number" -command \
	{xcircuit::textincrement [select get] -1; refresh}
$m add separator
$m add command -label "Make Label" -command \
	{set XCOps(labeltype) Text; set XCOps(labelimage) img_t; \
	.xcircuit.mainframe.toolbar.bt invoke}

set m2 [menu $m.fontmenu -tearoff 0]
$m2 add command -label "Add New Font" -command {xcircuit::promptnewfont}
$m2 add separator

set m2 [menu $m.stylemenu -tearoff 0]
$m2 add radio -label "Normal" -variable XCOps(fontstyle) -value normal \
	-command "xcircuit::label style normal"
$m2 add radio -label "Bold" -variable XCOps(fontstyle) -value bold \
	-command "xcircuit::label style bold"
$m2 add radio -label "Italic" -variable XCOps(fontstyle) -value italic \
	-command "xcircuit::label style italic"
$m2 add radio -label "BoldItalic" -variable XCOps(fontstyle) -value bolditalic \
	-command "xcircuit::label style bolditalic"
$m2 add separator
$m2 add radio -label "Subscript" -variable XCOps(fontscript) -value subscript \
	-command "xcircuit::label insert subscript"
$m2 add radio -label "Superscript" -variable XCOps(fontscript) -value superscript \
	-command "xcircuit::label insert superscript"
$m2 add radio -label "Normalscript" -variable XCOps(fontscript) -value normal \
	-command "xcircuit::label insert normalscript"
$m2 add separator
$m2 add radio -label "Underline" -variable XCOps(fontlining) -value underline \
	-command "xcircuit::label insert underline"
$m2 add radio -label "Overline" -variable XCOps(fontlining) -value overline \
	-command "xcircuit::label insert overline"
$m2 add radio -label "No Line" -variable XCOps(fontlining) -value normal \
	-command "xcircuit::label insert noline"

set m2 [menu $m.encodingmenu -tearoff 0]
$m2 add radio -label "Standard" -variable XCOps(fontencoding) -value Standard \
	-command "xcircuit::label encoding Standard"
$m2 add radio -label "ISOLatin1" -variable XCOps(fontencoding) -value ISOLatin1 \
	-command "xcircuit::label encoding ISOLatin1"

set m2 [menu $m.insertmenu -tearoff 0]
$m2 add command -label "Tab stop" -command "xcircuit::label insert stop"
$m2 add command -label "Tab forward" -command "xcircuit::label insert forward"
$m2 add command -label "Tab backward" -command "xcircuit::label insert backward"
$m2 add command -label "Carriage Return" -command "xcircuit::label insert return"
$m2 add command -label "1/2 space" -command "xcircuit::label insert halfspace"
$m2 add command -label "1/4 space" -command "xcircuit::label insert quarterspace"
$m2 add command -label "Kern" -command "xcircuit::promptkern"
$m2 add command -label "Character" -command "xcircuit::label insert special"
$m2 add command -label "Parameter" -command "xcircuit::label insert parameter"

set m2 [menu $m.justifymenu -tearoff 0]
$m2 add radio -label "Left Justified" -variable XCOps(jhoriz) -value left \
	-command "xcircuit::label justify left"
$m2 add radio -label "Center Justified" -variable XCOps(jhoriz) -value center \
	-command "xcircuit::label justify center"
$m2 add radio -label "Right Justified" -variable XCOps(jhoriz) -value right \
	-command "xcircuit::label justify right"
$m2 add separator
$m2 add radio -label "Top Justified" -variable XCOps(jvert) -value top \
	-command "xcircuit::label justify top"
$m2 add radio -label "Middle Justified" -variable XCOps(jvert) -value middle \
	-command "xcircuit::label justify middle"
$m2 add radio -label "Bottom Justified" -variable XCOps(jvert) -value bottom \
	-command "xcircuit::label justify bottom"
$m2 add separator
$m2 add check -label "Flip Invariant" -variable XCOps(flipinvariant) -onvalue true \
	-offvalue false -command {xcircuit::label flipinvariant $XCOps(flipinvariant)}

set m [menu .xcircuit.menubar.optionsbutton.optionsmenu -tearoff 0]
$m add check -label "Alt Colors" -variable XCOps(colorscheme) -onvalue alternate \
	-offvalue normal -command {xcircuit::config colorscheme $XCOps(colorscheme)}
$m add check -label "Show Bounding Box" -variable XCOps(showbbox) -onvalue visible \
	-offvalue invisible -command {xcircuit::config bbox $XCOps(showbbox)}
$m add check -label "Edit In Place" -variable XCOps(editinplace) -onvalue true \
	-offvalue false -command {xcircuit::config editinplace $XCOps(editinplace)}
$m add check -label "Show Pin Positions" -variable XCOps(pinpositions) -onvalue visible \
	-offvalue invisible -command {xcircuit::config pinpositions $XCOps(pinpositions)}
$m add command -label "Disable XSchema" -command {xcircuit::xschema disable}
$m add command -label "Disable Toolbar" -command {xcircuit::toolbar disable}
$m add cascade -label "Grid" -menu $m.gridmenu
$m add cascade -label "Snap-to" -menu $m.snapmenu
$m add cascade -label "Linewidth" -menu $m.linemenu
$m add cascade -label "Elements" -menu $m.elementsmenu
$m add separator
$m add command -label "Help!" -command {xcircuit::helpwindow}

set m2 [menu $m.gridmenu -tearoff 0]
$m2 add check -label "Grid" -variable XCOps(showgrid) -onvalue true -offvalue false \
	-command {xcircuit::config grid $XCOps(showgrid); refresh}
$m2 add check -label "Axes" -variable XCOps(showaxes) -onvalue true -offvalue false \
	-command {xcircuit::config axes $XCOps(showaxes); refresh}
$m2 add command -label "Grid Spacing" -command {xcircuit::promptgridspace}
$m2 add cascade -label "Grid type/display" -menu $m2.gridsubmenu

set m3 [menu $m2.gridsubmenu -tearoff 0]
$m3 add radio -label "Decimal Inches" -variable XCOps(gridstyle) \
	-value "decimal inches" \
	-command {xcircuit::config coordstyle $XCOps(gridstyle)}
$m3 add radio -label "Fractional Inches" -variable XCOps(gridstyle) \
	-value "fractional inches" \
	-command {xcircuit::config coordstyle $XCOps(gridstyle)}
$m3 add radio -label "Centimeters" -variable XCOps(gridstyle) -value "centimeters" \
	-command {xcircuit::config coordstyle $XCOps(gridstyle)}
$m3 add radio -label "Internal Units" -variable XCOps(gridstyle) \
	-value "internal units" \
	-command {xcircuit::config coordstyle $XCOps(gridstyle)}
$m3 add separator
$m3 add command -label "Drawing Scale" -command {xcircuit::promptdrawingscale}

set m2 [menu $m.snapmenu -tearoff 0]
$m2 add check -label "Snap-to" -variable XCOps(showsnap) -onvalue true -offvalue false \
	-command {xcircuit::config snap $XCOps(showsnap); refresh}
$m2 add command -label "Snap Spacing" -command {xcircuit::promptsnapspace}

set m2 [menu $m.linemenu -tearoff 0]
$m2 add command -label "Wire Linewidth" -command {xcircuit::promptborderwidth}
$m2 add command -label "Global Linewidth" -command {xcircuit::promptlinewidth}

set m2 [menu $m.elementsmenu -tearoff 0]
$m2 add cascade -label "Border" -menu $m2.bordermenu
$m2 add cascade -label "Fill" -menu $m2.fillmenu
$m2 add cascade -label "Color" -menu $m2.colormenu
$m2 add separator
$m2 add cascade -label "Parameters" -menu $m2.parammenu
$m2 add command -label "Scale" -command {xcircuit::promptelementsize}
$m2 add check -label "Center Object" -variable XCOps(centerobject) -onvalue true \
	-offvalue false -command {xcircuit::config centering $XCOps(centerobject)}
$m2 add check -label "Manhattan Draw" -variable XCOps(manhattandraw) -onvalue true \
	-offvalue false -command {xcircuit::config manhattan $XCOps(manhattandraw)}
$m2 add cascade -label "Polygon Edit" -menu $m2.polyeditmenu

set m3 [menu $m2.bordermenu -tearoff 0]
$m3 add command -label "Linewidth" -command {xcircuit::promptborderwidth}
$m3 add separator
$m3 add radio -label "Solid" -variable XCOps(linestyle) -value solid \
	-command {xcircuit::border $XCOps(linestyle)}
$m3 add radio -label "Dashed" -variable XCOps(linestyle) -value dashed \
	-command {xcircuit::border $XCOps(linestyle)}
$m3 add radio -label "Dotted" -variable XCOps(linestyle) -value dotted \
	-command {xcircuit::border $XCOps(linestyle)}
$m3 add radio -label "Unbordered" -variable XCOps(linestyle) -value unbordered \
	-command {xcircuit::border $XCOps(linestyle)}
$m3 add separator
$m3 add check -label "Closed" -variable XCOps(polyclosed) -onvalue closed \
	-offvalue unclosed -command {xcircuit::border  $XCOps(polyclosed)}
$m3 add check -label "Square Endcaps" -variable XCOps(endcaps) -onvalue square \
	-offvalue round -command {xcircuit::border  $XCOps(endcaps)}
$m3 add check -label "Bounding Box" -variable XCOps(bboxtype) -onvalue true \
	-offvalue false -command {xcircuit::border bbox $XCOps(bboxtype)}

# stipple images
image create bitmap img_stip0 -foreground white -background black -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/solid.xbm
image create bitmap img_stip12 -foreground black -background white -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/stip12.xbm
image create bitmap img_stip25 -foreground black -background white -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/stip25.xbm
image create bitmap img_stip38 -foreground black -background white -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/stip38.xbm
image create bitmap img_stip50 -foreground black -background white -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/stip50.xbm
image create bitmap img_stip62 -foreground black -background white -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/stip62.xbm
image create bitmap img_stip75 -foreground black -background white -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/stip75.xbm
image create bitmap img_stip88 -foreground black -background white -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/stip88.xbm
image create bitmap img_stip100 -foreground black -background white -file \
	${XCIRCUIT_LIB_DIR}/pixmaps/solid.xbm

set m3 [menu $m2.fillmenu -tearoff 0]
$m3 add radio -image img_stip100 -variable XCOps(fillamount) -value 100 \
	-command {xcircuit::fill $XCOps(fillamount) opaque}
$m3 add radio -image img_stip88 -variable XCOps(fillamount) -value 88 \
	-command {xcircuit::fill $XCOps(fillamount) opaque}
$m3 add radio -image img_stip75 -variable XCOps(fillamount) -value 75 \
	-command {xcircuit::fill $XCOps(fillamount) opaque}
$m3 add radio -image img_stip62 -variable XCOps(fillamount) -value 62 \
	-command {xcircuit::fill $XCOps(fillamount) opaque}
$m3 add radio -image img_stip50 -variable XCOps(fillamount) -value 50 \
	-command {xcircuit::fill $XCOps(fillamount) opaque}
$m3 add radio -image img_stip38 -variable XCOps(fillamount) -value 38 \
	-command {xcircuit::fill $XCOps(fillamount) opaque}
$m3 add radio -image img_stip25 -variable XCOps(fillamount) -value 25 \
	-command {xcircuit::fill $XCOps(fillamount) opaque}
$m3 add radio -image img_stip12 -variable XCOps(fillamount) -value 12 \
	-command {xcircuit::fill $XCOps(fillamount) opaque}
$m3 add radio -image img_stip0 -variable XCOps(fillamount) -value 0 \
	-command {xcircuit::fill $XCOps(fillamount) transparent}
$m3 add separator
$m3 add radio -label "Opaque" -variable XCOps(opaque) -value true \
	-command {xcircuit::fill opaque}
$m3 add radio -label "Transparent" -variable XCOps(opaque) -value false \
	-command {xcircuit::fill transparent}

set m3 [menu $m2.colormenu -tearoff 0]
$m3 add command -label "Add New Color" -command {xcircuit::picknewcolor}
$m3 add separator
$m3 add radio -label "Inherit Color" -variable XCOps(colorval) -value inherit \
  -command {color set inherit}

set m3 [menu $m2.parammenu -tearoff 0]
$m3 add command -label "Edit Parameters" -command \
	{xcircuit::prompteditparams {substring numeric expression}}
$m3 add separator
$m3 add check -label "Substring" -variable XCOps(substringparam) -onvalue true \
	-offvalue false -command {if {$XCOps(substringparam)} \
		{xcircuit::promptmakeparam} \
		{xcircuit::parameter forget substring}}
$m3 add check -label "Numeric" -variable XCOps(numericparam) -onvalue true \
	-offvalue false -command {if {$XCOps(numericparam)} \
		{xcircuit::promptmakeparam numeric} \
		{xcircuit::parameter forget numeric}}
$m3 add check -label "Style" -variable XCOps(styleparam) -onvalue true \
	-offvalue false -command {if {$XCOps(styleparam)} \
		{xcircuit::parameter make style} \
		{xcircuit::parameter forget style}}
$m3 add check -label "Justification" -variable XCOps(justparam) -onvalue true \
	-offvalue false -command {if {$XCOps(justparam)} \
		{xcircuit::parameter make justification} \
		{xcircuit::parameter forget justification}}
$m3 add check -label "Start Angle" -variable XCOps(startparam) -onvalue true \
	-offvalue false -command {if {$XCOps(startparam)} \
		{xcircuit::parameter make "start angle"} \
		{xcircuit::parameter forget "start angle"}}
$m3 add check -label "End Angle" -variable XCOps(endparam) -onvalue true \
	-offvalue false -command {if {$XCOps(endparam)} \
		{xcircuit::parameter make "end angle"} \
		{xcircuit::parameter forget "end angle"}}
$m3 add check -label "Radius" -variable XCOps(radiusparam) -onvalue true \
	-offvalue false -command {if {$XCOps(radiusparam)} \
		{xcircuit::parameter make radius} \
		{xcircuit::parameter forget radius}}
$m3 add check -label "Minor Axis" -variable XCOps(minorparam) -onvalue true \
	-offvalue false -command {if {$XCOps(minorparam)} \
		{xcircuit::parameter make "minor axis"} \
		{xcircuit::parameter forget "minor axis"}}
$m3 add check -label "Rotation" -variable XCOps(rotationparam) -onvalue true \
	-offvalue false -command {if {$XCOps(rotationparam)} \
		{xcircuit::parameter make rotation} \
		{xcircuit::parameter forget rotation}}
$m3 add check -label "Scale" -variable XCOps(scaleparam) -onvalue true \
	-offvalue false -command {if {$XCOps(scaleparam)} \
		{xcircuit::parameter make scale} \
		{xcircuit::parameter forget scale}}
$m3 add check -label "Linewidth" -variable XCOps(linewidthparam) -onvalue true \
	-offvalue false -command {if {$XCOps(linewidthparam)} \
		{xcircuit::parameter make linewidth} \
		{xcircuit::parameter forget linewidth}}
$m3 add check -label "Color" -variable XCOps(colorparam) -onvalue true \
	-offvalue false -command {if {$XCOps(colorparam)} \
		{xcircuit::parameter make color} \
		{xcircuit::parameter forget color}}
$m3 add check -label "Position" -variable XCOps(positionparam) -onvalue true \
	-offvalue false -command {if {$XCOps(positionparam)} \
		{xcircuit::parameter make position} \
		{xcircuit::parameter forget position}}
$m3 add check -label "Expression" -variable XCOps(expressparam) -onvalue true \
	-offvalue false -command {if {$XCOps(expressparam)} \
		{xcircuit::promptmakeparam expression} \
		{xcircuit::parameter forget expression}}

set m3 [menu $m2.polyeditmenu -tearoff 0]
$m3 add radio -label "Manhattan Box Edit" -variable XCOps(polyedittype) \
    -value manhattan -command {xcircuit::config boxedit $XCOps(polyedittype)}
$m3 add radio -label "Rhomboid X" -variable XCOps(polyedittype) \
    -value rhomboidx -command {xcircuit::config boxedit $XCOps(polyedittype)}
$m3 add radio -label "Rhomboid Y" -variable XCOps(polyedittype) \
    -value rhomboidy -command {xcircuit::config boxedit $XCOps(polyedittype)}
$m3 add radio -label "Rhomboid A" -variable XCOps(polyedittype) \
    -value rhomboida -command {xcircuit::config boxedit $XCOps(polyedittype)}
$m3 add radio -label "Normal" -variable XCOps(polyedittype) \
    -value normal -command {xcircuit::config boxedit $XCOps(polyedittype)}

set m [menu .xcircuit.menubar.windowbutton.windowmenu -tearoff 0]
$m add command -label "Zoom In" -command {zoom 1.5; refresh}
$m add command -label "Zoom Out" -command {zoom [expr {1 / 1.5}]; refresh}
$m add command -label "Pan" -command {.xcircuit.mainframe.toolbar.bp invoke}
$m add command -label "Full View" -command {zoom view; refresh}
$m add command -label "Refresh" -command {refresh}
$m add separator
$m add command -label "Library Directory" -command {xcircuit::library directory}
$m add cascade -label "Goto Library" -menu $m.librarymenu
$m add separator
$m add command -label "Page Directory" -command {xcircuit::page directory}
$m add cascade -label "Goto Page" -menu $m.pagemenu

set m2 [menu $m.librarymenu -tearoff 0]
$m2 add command -label "New Library Page" -command {xcircuit::promptaddlibrary}
$m2 add separator

set m2 [menu $m.pagemenu -tearoff 0]
$m2 add command -label "Add New Page" -command {xcircuit::page make}
$m2 add separator

set m [menu .xcircuit.menubar.netlistbutton.netlistmenu -tearoff 0]
$m add command -label "Make Pin" -command \
	{set XCOps(labeltype) "Pin Label"; set XCOps(labelimage) img_tp; \
	 .xcircuit.mainframe.toolbar.bt invoke}
$m add command -label "Make Info Pin" -command \
	{set XCOps(labeltype) "Info Label"; set XCOps(labelimage) img_ti; \
	.xcircuit.mainframe.toolbar.bt invoke}
$m add command -label "Make Global Pin" -command \
	{set XCOps(labeltype) "Pin Global"; set XCOps(labelimage) img_tg; \
	.xcircuit.mainframe.toolbar.bt invoke}
$m add cascade -label "Convert Label To..." -menu $m.pinmenu
$m add check -label "Pin Visibility" -variable XCOps(pinvisible) -onvalue true \
	-offvalue false -command {xcircuit::label visible $XCOps(pinvisible)}
$m add command -label "Make Matching Symbol" -command \
	{xcircuit::promptmakesymbol [page label]}
$m add command -label "Associate With Symbol" -command {xcircuit::symbol associate}
$m add command -label "Highlight Connectivity" -command {xcircuit::netlist highlight}
$m add command -label "Auto-number Components" -command {xcircuit::netlist autonumber}
$m add command -label "Un-number Components" -command \
	{xcircuit::netlist autonumber -forget}
$m add separator
$m add check -label "SPICE .end statement" -variable XCOps(spiceend) -onvalue true \
	-offvalue false
$m add check -label "Always regenerate netlists" -variable XCOps(forcenets) \
	-onvalue true -offvalue false
$m add separator
$m add command -label "Write SPICE netlist" -command \
	{if {$XCOps(forcenets)} {xcircuit::netlist make -force}; \
	 xcircuit::netlist write spice $XCOps(spiceend)}
$m add command -label "Write flattened SPICE" -command \
	{if {$XCOps(forcenets)} {xcircuit::netlist make -force}; \
	xcircuit::netlist write spiceflat}
$m add command -label "Write sim" -command \
	{if {$XCOps(forcenets)} {xcircuit::netlist make -force}; \
	xcircuit::netlist write sim}
$m add command -label "Write pcb" -command \
	{if {$XCOps(forcenets)} {xcircuit::netlist make -force}; \
	xcircuit::netlist write pcb}

set m2 [menu $m.pinmenu -tearoff 0]
$m2 add command -label "Normal label" -command {xcircuit::label type normal}
$m2 add command -label "Local Pin" -command {xcircuit::label type pin}
$m2 add command -label "Global Pin" -command {xcircuit::label type global}
$m2 add command -label "Info label" -command {xcircuit::label type info}

#-------------------------------------------------
# Create the cloned menu links used by the toolbar
#-------------------------------------------------

.xcircuit.menubar.optionsbutton.optionsmenu.elementsmenu.parammenu clone .parammenu
.xcircuit.menubar.optionsbutton.optionsmenu.elementsmenu.colormenu clone .colormenu
.xcircuit.menubar.optionsbutton.optionsmenu.elementsmenu.bordermenu clone .bordermenu
.xcircuit.menubar.optionsbutton.optionsmenu.elementsmenu.fillmenu clone .fillmenu

#-----------------------------------------
# Create the toolbar and associated tools
#-----------------------------------------

xcircuit::createtoolbar
xcircuit::arrangetoolbar
xcircuit::modebutton .xcircuit.mainframe.toolbar.bw

#-----------------------------------------------------------------
# Final setup stuff before exiting back to interpreter
#-----------------------------------------------------------------

# Add buttons for the pre-allocated pages

xcircuit::newpagebutton "Page 1" 1
xcircuit::newpagebutton "Page 2" 2
xcircuit::newpagebutton "Page 3" 3
xcircuit::newpagebutton "Page 4" 4
xcircuit::newpagebutton "Page 5" 5
xcircuit::newpagebutton "Page 6" 6
xcircuit::newpagebutton "Page 7" 7
xcircuit::newpagebutton "Page 8" 8
xcircuit::newpagebutton "Page 9" 9
xcircuit::newpagebutton "Page 10" 10

# Add buttons for the pre-allocated libraries

xcircuit::newlibrarybutton "User Library"

# New key bindings should pass through this function so that key
# strokes are captured correctly for label editing.

proc xcircuit::keyaction {keycode {keystate 0}} {
   switch -- [eventmode] {
      text -
      etext -
      cattext {
	 standardaction $keycode down $keystate
	 return true
      }
   }
   return false
}

#-----------------------------------------------------------------

proc scrollboth { lists args } {
   foreach l $lists {
      eval {$l yview} $args
   }
}

#-----------------------------------------------------------------

proc xcircuit::printhelp {} {
   set csel [.help.listwin.func curselection]
   if {$csel == ""} {return}
   set key [.help.listwin.func get $csel]
   switch -glob $key {
      {Page} {.help.listwin.win configure -text \
	"Switch to the indicated page."}
      {Justify} {.help.listwin.win configure -text \
	"Change justification of the currently selected or\
	edited label."}
      {Text Delete} {.help.listwin.win configure -text \
	"When editing a label, delete one character."}
      {Text Return} {.help.listwin.win configure -text \
	"When editing a label, accept edits and return to normal drawing mode."}
      {Text Left} {.help.listwin.win configure -text \
	"When editing a label, move cursor left one character or procedure."}
      {Text Right} {.help.listwin.win configure -text \
	"When editing a label, move cursor right one character or procedure."}
      {Text Up} {.help.listwin.win configure -text \
	"When editing a multi-line label, move cursor up one line of text."}
      {Text Down} {.help.listwin.win configure -text \
	"When editing a multi-line label, move cursor down one line of text."}
      {Text Split} {.help.listwin.win configure -text \
	"When editing a label, split the label into two separate labels at\
	the cursor position."}
      {Text Home} {.help.listwin.win configure -text \
	"When editing a label, move cursor to the beginning of the label."}
      {Text End} {.help.listwin.win configure -text \
	"When editing a label, move cursor to the end of the label."}
      {Tab Forward} {.help.listwin.win configure -text \
	"When editing a label, move forward to the next defined tab stop."}
      {Tab Backward} {.help.listwin.win configure -text \
	"When editing a label, move backward to the previously defined tab stop."}
      {Tab Stop} {.help.listwin.win configure -text \
	"When editing a label, declare a tab stop at the current horizontal cursor\
	 position.  This may be used to align text in multiple lines to certain\
	 positions."}
      {Superscript} {.help.listwin.win configure -text \
	"When editing a label, make text superscripted (about 2/3 size, and\
	raised about half a line)."}
      {Subscript} {.help.listwin.win configure -text \
	"When editing a label, make text subscripted (about 2/3 size, and\
	lowered about 3/4 of a line)."}
      {Normalscript} {.help.listwin.win configure -text \
	"When editing a label, return from a subscript or superscript alignment\
	to a normal text alignment."}
      {Nextfont} {.help.listwin.win configure -text \
	"When editing a label, change the font at the cursor position to the\
	next font family in the list.  This will cycle through all of the\
	defined fonts if executed repeatedly."}
      {Boldfont} {.help.listwin.win configure -text \
	"When editing a label, change the current font family to a boldface\
	type, if available."}
      {Italicfont} {.help.listwin.win configure -text \
	"When editing a label, change the current font family to an italic\
	or slanted type, if available."}
      {Normalfont} {.help.listwin.win configure -text \
	"When editing a label, change the current font family to a regular\
	type (non-italic, non-bold)."}
      {Underline} {.help.listwin.win configure -text \
	"When editing a label, begin underlining the text."}
      {Overline} {.help.listwin.win configure -text \
	"When editing a label, begin overlining the text."}
      {ISO Encoding} {.help.listwin.win configure -text \
	"When editing a label, change the font encoding from normal to ISO."}
      {Linebreak} {.help.listwin.win configure -text \
	"When editing a label, append a linebreak to the label.  This generates\
	multi-line text."}
      {Halfspace} {.help.listwin.win configure -text \
	"When editing a label, insert a half-space."}
      {Quarterspace} {.help.listwin.win configure -text \
	"When editing a label, insert a quarter-space."}
      {Special} {.help.listwin.win configure -text \
	"When editing a label, insert a special character.  This is a command\
	that brings up the font encoding array, allowing the user to select\
	any character from the current font in the current encoding type."}
      {Parameter} {.help.listwin.win configure -text \
	"When editing a label, insert a parameter.  The parameter must first\
	exist in the current object.  If only one parameter is defined, it\
	will be inserted.  If more than one parameter is defined, a selection\
	box will appear, allowing the user to select which parameter to\
	insert into the text."}
      {Parameterize Point} {.help.listwin.win configure -text \
	"When editing a polygon, parameterize the X and Y position of the\
	currently edited point.  The point may then be at a different\
	position in different instances of the current object."}
      {Break at Point} {.help.listwin.win configure -text \
	"When editing a polygon, break the polygon into two pieces at\
	the currently edited point."}
      {Delete Point} {.help.listwin.win configure -text \
	"When editing a polygon, remove the currently edited point, and\
	move to the next point."}
      {Insert Point} {.help.listwin.win configure -text \
	"When editing a polygon, insert a point at the same position as\
	the currently edited point."}
      {Append Point} {.help.listwin.win configure -text \
	"When editing a polygon, append a point at the same position as\
	the currently edited point, and move the currently edited point\
	to the new point."}
      {Next Point} {.help.listwin.win configure -text \
	"When editing a polygon, move to the next point."}
      {Attach} {.help.listwin.win configure -text \
	"When editing a polygon, select the nearest element that is not\
	the polygon, and force the currently edited point to terminate\
	on that element.  The element to attach to may be a polygon, an\
	arc, a spline, or a path.  The edit point will continue to follow\
	the cursor within the constraint that it must remain connected to\
	the other element."}
      {Virtual Copy} {.help.listwin.win configure -text \
	"Create a virtual library instance of the currently selected\
	object instance.  This will duplicate the existing library entry\
	but will have the scale and rotation of the selected instance,\
	as well as any non-default parameters given to that instance."}
      {Next Library} {.help.listwin.win configure -text \
	"When on a library page, go to the next defined library.  The\
	User Library is always last, and then the function cycles back\
	to the first defined library."}
      {Library Directory} {.help.listwin.win configure -text \
	"Go to the master list of libraries."}
      {Library Copy} {.help.listwin.win configure -text \
	"When on a library page, select the object under the cursor and\
	any selected objects, and return to the originating page in\
	copy mode."}
      {Library Edit} {.help.listwin.win configure -text \
	"When on a library page, edit the name of an object by editing\
	the text label underneath the picture of the object."}
      {Library Delete} {.help.listwin.win configure -text \
	"When on a library page, remove the selected object from the\
	library.  An object can be removed only if there are no instances\
	of that object on any page or in the hierarchy of another object.\
	A removed object is destroyed and cannot be recovered."}
      {Library Duplicate} {.help.listwin.win configure -text \
	"When on a library page, create a duplicate object of the selected\
	object, placing it in the User Library."}
      {Library Hide} {.help.listwin.win configure -text \
	"When on a library page, remove the selected object from view but\
	do not destroy it.  An object can be hidden from view only if\
	it exists in the hierarchy of another object (such as the arrow
	object inside the current source object)."}
      {Library Virtual Copy} {.help.listwin.win configure -text \
	"When on a library page, create a duplicate instance of the\
	selected object.  The duplicate instance may have different\
	(instanced) parameters.  Default parameters are defined by\
	the master object.  The name of the master object is printed\
	in black, while the names of virtual instances are in gray.\
	To define a virtual copy with different scale or rotation,\
	use the (non-Library) Virtual Copy function."}
      {Library Move} {.help.listwin.win configure -text \
	"When on a library page, move the position of an object relative\
	to other objects.  If one object is selected, it will be moved\
	to the position nearest the cursor.  If two objects are selected,\
	their positions will be swapped.  If in the Page Directory, the\
	relative positions of pages may be changed with the same function."}
      {Library Pop} {.help.listwin.win configure -text \
	"When on a library page, return to the originating page."}
      {Page Directory} {.help.listwin.win configure -text \
	"Go to the master list of pages."}
      {Help} {.help.listwin.win configure -text \
	"Display the window of help information and key bindings."}
      {Redraw} {.help.listwin.win configure -text \
	"Redraw everything in the window."}
      {View} {.help.listwin.win configure -text \
	"Scale and position the view of the current page so that elements\
	on the page fill the window to the maximum extent possible (minus\
	small margins on all sides)."}
      {Zoom In} {.help.listwin.win configure -text \
	"Increase the magnification of the view of the current page in\
	the window.  The location of the page at the center point of the\
	window remains at the center."}
      {Zoom Out} {.help.listwin.win configure -text \
	"Decrease the magnification of the view of the current page in\
	the window.  The location of the page at the center point of the\
	window remains at the center."}
      {Pan} {.help.listwin.win configure -text \
	"Change the view of the current page.  There are various modes,\
	including here, center, left, right, up, down, and follow.  Pan\
	center changes the view such that the point nearest\
	the cursor becomes the center point of the window. Pan up, down,\
	right, and left change the view by one-half page in the indicated\
	direction."}
      {Double Snap} {.help.listwin.win configure -text \
	"Increase the spacing between snap points by a factor of two."}
      {Halve Snap} {.help.listwin.win configure -text \
	"Decrease the spacing between snap points by half."}
      {Write} {.help.listwin.win configure -text \
	"Display the Output Properties and File Write window.  If output\
	properties are changed but user does not want to write the file\
	(such as when attaching multiple pages or schematics), use the\
	Cancel button to accept all applied changes and pop down the\
	window without writing."}
      {Rotate} {.help.listwin.win configure -text \
	"Rotate the selected elements, or element nearest the cursor, by\
	the number of degrees in the argument.  A positive number indicates\
	a clockwise rotation, a negative number, a counterclockwise\
	rotation."}
      {Flip X} {.help.listwin.win configure -text \
	"Flip the selected elements, or element nearest the cursor, in the\
	horizontal (X) direction (that is, across the Y axis).  The axis\
	defining the flip is the vertical line passing through the cursor X\
	position."}
      {Flip Y} {.help.listwin.win configure -text \
	"Flip the selected elements, or element nearest the cursor, in the\
	vertical (Y) direction (that is, across the X axis).  The axis\
	defining the flip is the horizontal line passing through the cursor\
	Y position."}
      {Snap} {.help.listwin.win configure -text \
	"Snap the selected elements, or element nearest the cursor, to the\
	nearest point on the snap grid.  Each point of a polygon is snapped.\
	Spline control points and arc centers are snapped.  Label and object\
	instance reference positions are snapped."}
      {Pop} {.help.listwin.win configure -text \
	"Return from editing an object (return from the last push)."}
      {Push} {.help.listwin.win configure -text \
	"Edit the object represented by the selected object instance, or the\
	object instance closest to the cursor.  The current page is pushed\
	onto a stack, and the object becomes the current page."}
      {Delete} {.help.listwin.win configure -text \
	"Delete the selected elements or element closest to the cursor."}
      {Select} {.help.listwin.win configure -text \
	"Select the element or elements near the cursor.  If multiple\
	elements match the selection criteria, an interactive method is\
	initiated in which individual elements may be selected or rejected\
	by pressing the mouse buttons 2 or 3, respectively."}
      {Box} {.help.listwin.win configure -text \
	"Begin drawing a box in the current default style.  One corner of\
	 the box is anchored at the cursor position, and the other corner\
	dragged with the cursor.  The box is completed by pressing buttons\
	1 or 2 or canceled with button 3."}
      {Arc} {.help.listwin.win configure -text \
	"Begin drawing a circle in the current default style.  The center\
	of the circle is anchored at the cursor position, and the radius\
	is defined by dragging the cursor to the desired position.  Button\
	2 completes the arc, and button 3 cancels it.  Button 1 switches\
	from defining the arc radius to (in sequence) defining the arc\
	start and stop angles, and defining the ellipse minor axis."}
      {Text} {.help.listwin.win configure -text \
	"Begin a normal text label.  In text edit mode, all keystrokes are\
	interpreted as input to the label, except for the key that is bound\
	to action Text Return.  Mouse buttons 1 and 2 complete the text\
	label, while button 3 cancels (deletes) the label."}
      {Exchange} {.help.listwin.win configure -text \
	"If two elements are selected, their relative positions (drawing\
	order) are swapped (drawing order determines what objects obscure\
	other objects when overlapping).  If one element is selected, it\
	is brought to the front of the drawing, unless it is already at\
	the front, in which case it is sent to the back."}
      {Copy} {.help.listwin.win configure -text \
	"Make a copy of the selected elements or element closest to the\
	cursor.  Elements are dragged as a group with the cursor.  Mouse\
	button 1 places the copies, creates a new set of copies, and\
	continues the copy operation.  Mouse button 2 places the copies\
	and ends the copy operation.  Mouse button 3 removes the current\
	selection being dragged and completes the copy operation."}
      {Move} {.help.listwin.win configure -text \
	"Move the selected elements or element nearest the cursor.  This\
	function is normally handled by the mouse button press, not the\
	Move binding."}
      {Join} {.help.listwin.win configure -text \
	"Join selected elements into a single element.  If all of the selected\
	elements are polygons, the new element will be a single polygon.  If\
	the selected elements include a mixture of one or more types\
	(polygons, arcs, splines, and paths), the resulting type will be a\
	path."}
      {Unjoin} {.help.listwin.win configure -text \
	"Break the selected path or path nearest the cursor into its\
	constituent elements.  This operation applies only to paths."}
      {Spline} {.help.listwin.win configure -text \
	"Begin a bezier curve (inconsistently and, technically, incorrectly\
	referred to in XCircuit documentation as a spline).  The curve is\
	anchored at the cursor position, and the other endpoint of the\
	curve is dragged with the cursor.  Mouse button 2 completes the\
	curve.  Mouse button 3 cancels (deletes) the curve.  Mouse button\
	1 switches between the two endpoints and two control points."}
      {Edit} {.help.listwin.win configure -text \
	"Edit the selected element or element nearest the cursor.  The\
	edit function applies to polygons, arcs, splines, paths, and\
	labels, but not to object instances (editing the instance implies\
	editing the object itself, which requires the Push function).\
	Editing a label, arc, or spline is the same as creating it.\
	Editing a polygon (including boxes and wires) allows individual\
	points to be selected and moved.  In all cases except labels,\
	mouse button 1 moves to the next point, mouse button 2 completes\
	the edit, and mouse button 3 cancels the last edit maneuver."}
      {Undo} {.help.listwin.win configure -text \
	"Undo the last action.  Note that not all actions are undoable."}
      {Redo} {.help.listwin.win configure -text \
	"Perform again the last action which was undone with the Undo\
	 function."}
      {Select Save} {.help.listwin.win configure -text \
	"Take all of the selected elements and turn them into a new\
	object.  The individual elements will be removed from the page\
	and replaced with an instance of the newly defined object, and\
	the object itself will be placed in the User Library.  The\
	user will be prompted for a name of the new library object."}
      {Unselect} {.help.listwin.win configure -text \
	"Remove the element closest to the cursor from the list of\
	currently selected objects."}
      {Dashed} {.help.listwin.win configure -text \
	"Set the border style of the selected elements or element\
	closest to the cursor to a dashed line."}
      {Dotted} {.help.listwin.win configure -text \
	"Set the border style of the selected elements or element\
	closest to the cursor to a dotted line."}
      {Solid} {.help.listwin.win configure -text \
	"Set the border style of the selected elements or element\
	closest to the cursor to a solid line."}
      {Prompt} {.help.listwin.win configure -text \
	"Generate the TCL command prompt."}
      {Dot} {.help.listwin.win configure -text \
	"Create a solder dot, connecting wires passing through it.  The\
	dot is placed at the current cursor position.  If a library\
	object named dot exists, it is used."}
      {Wire} {.help.listwin.win configure -text \
	"Begin drawing a wire (or unclosed polygon).  The wire is anchored\
	at the cursor position, and the other end is dragged with the\
	cursor.  Mouse button 1 anchors the endpoint and starts a new\
	wire segment.  Mouse button 2 anchors the endpoint and completes\
	the wire.  Mouse button 3 deletes the last anchored point."}
      {Nothing} {.help.listwin.win configure -text \
	"Null function.  Does nothing."}
      {Exit} {.help.listwin.win configure -text \
	"Exit the program immediately without prompting for action on\
	pages which have been changed but not saved."}
      {Start} {.help.listwin.win configure -text \
	"General-purpose start function, normally associated with mouse\
	button 1."}
      {Finish} {.help.listwin.win configure -text \
	"General-purpose completion function, normally associated with mouse\
	button 2."}
      {Cancel} {.help.listwin.win configure -text \
	"General-purpose cancelation function, normally associated with mouse\
	button 3."}
      {Snap To} {.help.listwin.win configure -text \
	"Toggle the state of the snapping function.  If on, points and element\
	positions are always snapped to the snap grid.  If off, points and\
	element position are unconstrained."}
      {Netlist} {.help.listwin.win configure -text \
	"Generate a netlist of the default type."}
      {Swap} {.help.listwin.win configure -text \
	"Switch between editing a schematic and its symbol.  If the schematic\
	covers multiple pages, will switch between the secondary page, primary\
	page, and symbol."}
      {Pin Label} {.help.listwin.win configure -text \
	"Create a local pin, a label that is interpreted as\
	the primary name of the network to which it is attached."}
      {Pin Global} {.help.listwin.win configure -text \
	"Create a global pin, a label that is interpreted as\
	belonging to the same network whereever it occurs on\
	the schematic."}
      {Info Label} {.help.listwin.win configure -text \
	"Create an info label, a label that is not displayed\
	except when editing the object, and which is parsed\
	to extract information on how to output the device in\
	a netlist."}
      {Connectivity} {.help.listwin.win configure -text \
	"Highlight the connectivity of the electrical network\
	 that includes the selected item or that is closest\
	 to the cursor.  Item must be a valid network element."}
      {Sim} {.help.listwin.win configure -text \
	"Generate a .sim (flat) netlist from the current page schematic,\
	especially for use with the IRSIM simulator and the netgen and\
	gemini LVS netlist comparators."}
      {SPICE} {.help.listwin.win configure -text \
	"Generate a .spc (hierarchical) netlist from the current page\
	schematic.  The format is compatible with Berkeley spice3 and\
	tclspice."}
      {PCB} {.help.listwin.win configure -text \
	"Generate a .pcbnet netlist from the current page schematic.\
	This format is compatible with the pcb layout program."}
      {SPICE Flat} {.help.listwin.win configure -text \
	"Generate a .fspc (flattened) SPICE netlist from the current\
	 page schematic."}
      {default} {.help.listwin.win configure -text ""}
   }
}

#-----------------------------------------------------------------
# Procedure to generate the help window
#-----------------------------------------------------------------

proc xcircuit::makehelpwindow {} {
   toplevel .help -bg beige
   wm withdraw .help

   frame .help.title -bg beige
   frame .help.listwin

   pack .help.title -side top -fill x
   pack .help.listwin -side top -fill both -expand true

   label .help.title.field -text "XCircuit Help" -bg beige
   button .help.title.dbut -text "Dismiss" -bg beige -command {wm withdraw .help}
   pack .help.title.field -side left -padx 10
   pack .help.title.dbut -side right -ipadx 10

   listbox .help.listwin.func -yscrollcommand ".help.listwin.sb set" \
	-setgrid 1 -height 20
   listbox .help.listwin.keys -yscrollcommand ".help.listwin.sb set" \
	-setgrid 1 -height 20
   scrollbar .help.listwin.sb -orient vertical -command \
	[list scrollboth [list .help.listwin.func .help.listwin.keys]]
   message .help.listwin.win -width 200 -justify left -anchor n \
	-relief groove -text "Click on a function for help text"

   grid .help.listwin.func -row 0 -column 0 -sticky news -padx 1 -pady 1
   grid .help.listwin.keys -row 0 -column 1 -sticky news -padx 1 -pady 1
   grid .help.listwin.sb -row 0 -column 2 -sticky ns -padx 1 -pady 1
   grid .help.listwin.win -row 0 -column 3 -sticky news -padx 1 -pady 1

   grid columnconfigure .help.listwin 1 -weight 1 -minsize 100
   grid rowconfigure .help.listwin 0 -weight 1 -minsize 100

   bind .help.listwin.func <ButtonRelease-1> "xcircuit::printhelp"
}

#-----------------------------------------------------------------
# Procedure to update and display the help window
#-----------------------------------------------------------------

proc xcircuit::helpwindow {} {

   # Create the help window if it doesn't exist
   if {[catch {wm state .help}]} {
      xcircuit::makehelpwindow
   }

   .help.listwin.func delete 0 end
   .help.listwin.keys delete 0 end

   set k [lsort -dictionary [xcircuit::bindkey]]

   .help.listwin.func insert end "Function"
   .help.listwin.keys insert end "Keys"
   .help.listwin.func insert end ""
   .help.listwin.keys insert end ""

   foreach i $k {
      set pkeys [xcircuit::bindkey -func $i]
      .help.listwin.func insert end "$i"
      .help.listwin.keys insert end "$pkeys"
   }

   wm deiconify .help
}

#-----------------------------------------------------------------
# Wrapper procedure to (re)bind a key to a Tcl procedure (Ed Casas 9/4/03)
# With no arguments, prints a list of bindings to stdout.
#-----------------------------------------------------------------

proc xcircuit::keybind { {key {}} {proc {}} } {
   switch -- $key {
      {} {
	puts stdout "XCircuit standard key bindings:"
	puts stdout "Key		Binding"
	puts stdout "-------------------------------------"
	set kpairs [xcircuit::bindkey]
	foreach i $kpairs {
	   set pkey [lindex $i 0]
	   set pval [lindex $i 1]
	puts stdout "$pkey		$pval"
	}
	puts stdout ""
      }
      default {
	bind .xcircuit.mainframe.mainarea.drawing \
	   $key "if \{!\[xcircuit::keyaction %k %s\]\} \{ $proc \}"
      }
   }
}

#-----------------------------------------------------------------
# Procedure to help with label generation (label autoincrement)
#-----------------------------------------------------------------

# autoincrement the first number found in the text of the indicated
# label(s).  Use argument "amount" to decrement, or increment by 10,
# etc.
#
# example:   xcircuit::textincrement [select get]

proc xcircuit::textincrement {handle {amount 1}} {
   foreach h $handle {
      if {[element $h type] == "Label"} {
         set tlist [join [label $h list]]
         set tlen [llength $tlist]
         for {set i 0} {$i < $tlen} {incr i} {
	    set t [lindex $tlist $i]
            set esc [lindex $t 0]
            if {$esc == "Text"} {
	       set ltext [lindex $t 1]
	       set num [regexp -inline {[+-]*[[:digit:]]+} $ltext]
	       if {$num != ""} {
	          incr num $amount
	          regsub {[+-]*[[:digit:]]+} $ltext $num ltext
	          set t [lreplace $t 1 1 $ltext]
	          set tlist [lreplace $tlist $i $i $t]
	          label $h replace $tlist
	          break
	       }
	    }
	 }
      }
   }
}


proc xcircuit::autoincr {{value 1}} {
   set s [select get]
   set e [eventmode]
   if {$e != "text" && $e != "etext" } {
      if {[llength $s] > 0} {
         xcircuit::textincrement $s $value
         select $s
         refresh
      } else {
	 error "no selection"
      }
   } else {
      error "no auto-incr in text mode"
   }
}

# The "catch" statement here allows "i" and "I" to have other bindings for
# normal mode (e.g., "I" for "make info label") when nothing is selected.

xcircuit::keybind i {if {[catch {xcircuit::autoincr}]} {standardaction %k down %s}}
xcircuit::keybind I {if {[catch {xcircuit::autoincr -1}]} {standardaction %k down %s}}

#-----------------------------------------------------------------
# Add key and button bindings for XCircuit commands (standard actions)
# These can be overridden by binding to specific keys and/or buttons.
#-----------------------------------------------------------------

bind .xcircuit.mainframe.mainarea.drawing <ButtonPress> {standardaction %b down %s}
bind .xcircuit.mainframe.mainarea.drawing <ButtonRelease> {standardaction %b up %s}
bind .xcircuit.mainframe.mainarea.drawing <KeyPress> {standardaction %k down %s}
bind .xcircuit.mainframe.mainarea.drawing <KeyRelease> {standardaction %k up %s}

# Here are some extra key functions that come with the TCL wrapper

bind .xcircuit.mainframe.mainarea.drawing <Key-Next> {catch {page [expr {[page] + 1}]}}
bind .xcircuit.mainframe.mainarea.drawing <Key-Prior> {catch {page [expr {[page] - 1}]}}
bind .xcircuit.mainframe.mainarea.drawing <Control-Key-p> \
	{xcircuit::prompteditparams {substring numeric expression}}

# Prevent "Tab" from removing focus from the window during text edits,
# but allow it to take its normal meaning at other times.

bind all <Tab> { 
   switch -- [eventmode] {                        
      text -
      etext -
      cattext {} 
      default {tk::TabToWindow [tk_focusNext %W]}
   }  
}  

bind all <<PrevWindow>> {
   switch -- [eventmode] {
      text -
      etext -
      cattext {}
      default {tk::TabToWindow [tk_focusPrev %W]}
   }
}

# Function bindings for the mouse scroll wheel.

xcircuit::keybind <Button-4> { pan up 0.05 ; refresh}
xcircuit::keybind <Button-5> { pan down 0.05 ; refresh}

bind .xcircuit.mainframe.mainarea.drawing <MouseWheel> { if {%k > 0} {pan up 0.05; refresh} else {pan down 0.05; refresh} }

# These are supposed to disable the scroll wheel on the scrollbars. . .

bind .xcircuit.mainframe.mainarea.sbleft <Button-4> {}
bind .xcircuit.mainframe.mainarea.sbleft <Button-5> {}
bind .xcircuit.mainframe.mainarea.sbbottom <Button-4> {}
bind .xcircuit.mainframe.mainarea.sbbottom <Button-5> {}

# Wait for the drawing area to become visible, and set the focus on it.

bind .xcircuit.mainframe.mainarea.drawing <Enter> {focus %W}
tkwait visibility .xcircuit.mainframe.mainarea.drawing
focus -force .xcircuit.mainframe.mainarea.drawing

# This pops down the interpreter window, if the "console.tcl" script was run.

catch xcircuit::consoledown

# End of GUI configuration file.  Xcircuit continues to load the xcircuit
# startup configuration files.
