#******************************************************************************
#***
#*** This file is part of XTeXShell; see file xtexsh for details
#*** Version 0.91 (21.2.94)
#***
#******************************************************************************
proc XTeXEdit {} {
#******************************************************************************
#*** Editor
#***
#*** Open a new window
#*** Load and edit the file $editfname. If $editfname == "", edit new file
#***
#*** Mode of editor is determined by variable editmode (TURBO, E2)
#***
#******************************************************************************
global col line
global editwin textbuf
global edit_font bold_font boldl_font fixboldl_font helvbold_font
global editfname editinfname
global editmod goto_command
global editins
global CMode trailing_spaces
global isColorX
set editwin ".mainwin.frame"
set editins "Insert"
set textbuf $editwin.txt
set editinfname [expr {[cequal "" $editfname] ? "(unnamed)" : $editfname} ]
set trailing_spaces 0
#*** Check if there is already a XTeXEdit window
if {[winfo exists $textbuf]} {
DisplayInfo "There is already a XTeX-Edit window!\nPlease end other XTeX-Edit session first" "$boldl_font"
return
}
#*** Check if file exists
if {![cequal "" $editfname] && ![file exists $editfname]} {
DisplayInfo "File: $editfname does not exist" "$boldl_font"
return
}
#*** Generate frame
frame $editwin
pack $editwin -fill both -padx 3m -pady 2m
if {$isColorX} {
$textbuf tag configure srchfound -font $edit_font -underline 1 \
-foreground red
} else {
$textbuf tag configure srchfound -font $edit_font \
-background black -foreground white
}
set goto_command ""
#*** Read file
if {![cequal "" $editfname]} {
ReadFile $editfname
resetmodflag
}
#*****************************************************************************
#****** Functions to enter Text or characters into editor ********************
#*****************************************************************************
proc InsChar {textbuf char} {
global col line
global editwrap editwrapcol edittrans edittrlist
global editins
if {[ctype ord $char] > 0} {
setmodflag
#*** Character Translation
if {$edittrans} {
set pos [lsearch -exact $edittrlist "\_$char\_"]
if {$pos > -1} {
set char [lindex $edittrlist [expr $pos+1]]
}
}
#*** Delete Mode ?
if {[cequal $editins "Delete"]} {
set len [clength "$char"]
set rlen [clength [$textbuf get $line.$col "$line.$col lineend"]]
if {$rlen < $len} {
set len $rlen
}
#*** Insert character in text. Check for Wrap-Mode
$textbuf insert $line.$col "$char"
if {$col > $editwrapcol && $editwrap && [string first $char " \n"]<0} {
set col [string last " " [$textbuf get "insert linestart" "insert"]]
incr col
if {$col>0} {$textbuf insert $line.$col "\n"}
}
}
#*** Set cursor
GotoXY $textbuf [$textbuf index insert]
}
}
proc InsertText {textbuf text} {
#*** Insert text into editor. Move cursor to end of text
#*** Insert text into editor, but only if editor exists.
#*** Remove all tabs and replace by spaces. Do not move cursor
global edittab textbuf boldl_font
if {![EditChkOpen]} {return}
set pos [$textbuf index insert]
InsertText $textbuf "$text"
#*** Now search through text in 512 byte blocks for tabs and replace them
#*** This routine must be very fast !!!!!
if {[string first "\t" $text] >= 0} {
DisplayMsg "Text contains Tabs.\n Replacing Tabs.\n Please Wait..." $boldl_font
for {set sblock 0} {1 < [clength [$textbuf get "0.0 + $sblock c" "0.0 + $sblock c + 2c"]]} {incr sblock 512} {
while {1} {
set tpos [string first "\t" [$textbuf get "0.0 + $sblock c" "0.0 + $sblock c + 512 c"]]
if {$tpos < 0} {break}
incr sblock $tpos
$textbuf mark set insert "0.0 + $sblock c"
$textbuf delete insert
set col [lindex [split [$textbuf index insert] "."] 1]
$textbuf insert insert [replicate " " [expr [expr $edittab * ($col / $edittab + 1)] - $col]]
}
}
}
#*** Set Cursor position
GotoXY $textbuf $pos
}
#*****************************************************************************
#****** Functions to change cursor position **********************************
#*****************************************************************************
proc GotoXY {textbuf pos {wcol -1}} {
#*** Move Cursor to position pos.
#*** If wcol>=0, goto column wcol. If column wcol does not exist
#*** because the line is shorter, insert spaces at end of line
#*** until wcol is reached. Remove extra spaces when cursor is moved to
#*** the next line.
global col line
global goto_command
#*** Calculate new position
set npos [$textbuf index "$pos"]
set nline [lindex [split $npos "."] 0]
set ncol [lindex [split $npos "."] 1]
#*** Execute goto_command command
eval $goto_command
set goto_command ""
#*** before the line changes, eat up ending spaces (if any)
if {$line != $nline} {
EatSpaces $textbuf $line.$col
}
#*** Set Cursor
while {1} {
$textbuf insert $npos ""
$textbuf mark set insert $npos
#*** Get Cursor position
set col [lindex [split [$textbuf index insert] "."] 1]
set line [lindex [split [$textbuf index insert] "."] 0]
#*** If wcol >=0, check if new column=wcol. If not, insert spaces until
#*** column==wcol. This is important for cursor up/down if line length
#*** is smaller than the requested column
if {$wcol >= 0 && $col < $wcol} {
set xpos [$textbuf index "$nline.0 lineend"]
$textbuf mark set insert $xpos
set len [expr $wcol - [lindex [split $xpos "."] 1]]
$textbuf insert insert [replicate " " $len]
set npos "$nline.$wcol"
set wcol -1
continue
}
proc But11 {textbuf x y} {
set tk_priv(selectMode) char
$textbuf mark set insert @$x,$y
$textbuf mark set anchor insert
if {[lindex [$textbuf config -state] 4] == "normal"} {focus $textbuf}
GotoXY $textbuf [$textbuf index insert]
}
proc But12 {textbuf x y} {
set tk_priv(selectMode) word
$textbuf mark set anchor "@$x,$y wordstart"
tk_textSelectTo $textbuf "@$x,$y wordend-1c"
}
proc But13 {textbuf x y} {
set tk_priv(selectMode) line
$textbuf mark set anchor "@$x,$y linestart"
tk_textSelectTo $textbuf "@$x,$y lineend"
}
#*****************************************************************************
#****** Check editor status **************************************************
#*****************************************************************************
proc EditChkOpen {{mode 1}} {
#*** Check if editor open.
#*** If not, (if mode=1 display warning message) and return false
global textbuf boldl_font
if {![info exists textbuf] || ![winfo exists $textbuf]} {
if {$mode == 1} {
DisplayInfo "Function does not work because you haven't startet the XTeX-editor yet" $boldl_font
}
return 0
}
return 1
}
#******************************************************************************
#*** Flags for modification of editor window **********************************
#******************************************************************************
proc setmodflag {} {
#*** Set Flag for modification
global editmod
if {[cequal $editmod ""]} {
set editmod "Mod"
}
}
#*** Include a file at current cursor position
#*** if fname == "", then ask for file name
global boldl_font textbuf
#*** Do we have an open edit window ?
if {![EditChkOpen]} {return}
#*** Yes. Do we have a valid filename? if fname="" then ask for filename
if {[cequal $fname ""]} {
set fname [FileSelBox OPEN]
if {[cequal $fname ""]} {return}
}
#*** Now read file
set fd [open $fname "r"]
InsertEditor [read $fd]
close $fd
}
proc ReLoadFile {} {
#*** Quit current File view and Re-Read file
global boldl_font
global editfname textbuf
#*** Do we have an open edit window and did we load a file or was it a new file?
if {![EditChkOpen] || [cequal "" $editfname]} {return}
#*** Ask user if he wants the file reload and load file
set retval [DisplayQuest "Re-Read file:\n\nCancel current editor window and Re-Read file?" \
$boldl_font "Yes" "No"]
if {$retval==1} {
$textbuf delete 0.0 end
ReadFile $editfname
resetmodflag
}
}
proc WriteFile {range fname} {
#*** Rename fname to fname~. Write range to file fname
#*** If fname == "", than ask for FileName
#*** return filename if operation successful, "" if error
global textbuf boldl_font
global line col
if {[cequal $fname ""]} {
set fname [FileSelBox CREATE]
if {[cequal $fname ""]} {return ""}
}
if {[file exists "$fname"]} {
catch {frename "$fname" "$fname~"}
}
set fd [open $fname "w"]
if {$fd <= 0} {
DisplayInfo "Can't open file\n$fname\nfor writing!\nOperation aborted!" $boldl_font
return ""
}
DisplayMsg "Writing to file\n $fname.\n Please wait..." $boldl_font
eval puts $fd $range
close $fd
sleep 1; #*** Wait and remove message in GotoXY function
GotoXY $textbuf $line.$col
return "$fname"
}
proc SaveFile {Mode} {
#*** Save file in editor. Mode="": Use editfname. Mode=="AS": Ask for filename
global textbuf editfname editinfname
#*** Do we have an open edit window ?
if {![EditChkOpen]} {return}
#*** Get filename
if {[cequal $Mode ""]} {
set retval [WriteFile {[$textbuf get 0.0 end]} "$editfname"]
} else {
set retval [WriteFile {[$textbuf get 0.0 end]} ""]
}
#*** Write file
if {![cequal $retval ""]} {
resetmodflag
set editfname "$retval"
set editinfname "$retval"
}
}
#*** Search/Replace Text
#*** func== "" : Display Search mask and search
#*** func== "REPLACE" : Display Replace mask and replace
#*** func== "CONTINUE" : Continue previous operation
global srch_win
global srch_mode srch_str srch_rep srch_case srch_prompt srch_dir srch_mode srch_pos
global srch_act srch_scope textbuf
global textbuf
if {![EditChkOpen]} {return}
if {![cequal $func "CONTINUE"] || ![info exists srch_pos]} {
set srch_mode [expr ![cequal $func "REPLACE"]]
#*** Create Search / Replace Window
set srch_win [CreateTopWin search "CREATE"]
if {$srch_mode} {set title "Search"}
if {!$srch_mode} {set title "Replace"}
wm title $srch_win $title
wm iconname $srch_win $title
#*** Create Frames which are used to place the entries on the screen
#*** Search / Replace from Top / End of file ? Set srch_pos
if {[cequal $srch_scope "FILE"]} {
if {$srch_dir} {
set srch_pos 0
} else {
set srch_pos [string length [$textbuf get 0.0 end]]
}
SrchRep
focus $textbuf
return
}
}
#*** Srch / Replace from Cursor ? Set srch_pos to current cursor
set srch_pos [string length [$textbuf get 0.0 insert]]
if {$srch_dir} {
incr srch_pos
}
SrchRep
focus $textbuf
}
proc SrchRep {} {
#*** Search / Replace
#*** srch_mode: true: Search, false: Replace
#*** srch_str: String to search
#*** srch_rep: String to replace
#*** srch_case: Case sensitive ?
#*** srch_prompt: Prompt on replace ?
#*** srch_dir: true = forward, false = backward
#*** srch_act: "1" Search next "ALL" Replace all
#*** srch_pos: Position (in chars) where to start with search
global srch_mode srch_str srch_rep srch_case srch_prompt srch_dir srch_mode srch_pos srch_act
global textbuf line col goto_command
global boldl_font
set rep_num 0; #*** Number of replacements
#*** Get Search-String to str. If case independant search, convert to upper
set str "$srch_str"
if {!$srch_case} {set str [string toupper "$str"]}
set str_len [clength $str]
while (1) {
#*** Copy Text-Range to search to text... If case independant, convert to upper case...
#*** Search entry. If found, set pos to position in textbuf, srch_pos to position for
#*** next search / replace
if {$srch_dir} {
set text [$textbuf get "0.0 + $srch_pos chars" end]
} else {
set text [$textbuf get "0.0" "0.0 + $srch_pos chars"]
}
if {!$srch_case} {set text [string toupper "$text"]}
if {$srch_dir} {
set pos [string first "$str" "$text"]
set curpos [expr $srch_pos+$pos]
} else {
set pos [string last "$str" "$text"]
set curpos $pos
}
#*** No entry found ? Tell User if Search-Mode. If Replace-Mode, everything is fine...
if {$pos < 0} {
if {$rep_num == 0} {
DisplayInfo "Search:\n$str\n not found" $boldl_font
} else {
DisplayMsg "Replace:\n$rep_num\nreplacements made" $boldl_font
sleep 1
}
set srch_pos 1000000
focus $textbuf
GotoXY $textbuf $line.$col
return
}
#*** Entry found, set cursor to word and highlight
#******************************************************************************
#*** Edit: Select editor and edit file ****************************************
#******************************************************************************
proc Edit fname {
#*** Call Editor
#*** fname = "\n" : Display file selector box and let user choose a file to edit
#*** fname = "" : Create a new file
#*** default : Edit file fname
global editfname editinfname editor editwin
global editfilelist
global boldl_font
#*** The XTeX built-in editor can handle only one file at a time.
#*** Check if XTeX editor is selected and if there is already a modified file in the editor
set editor [string tolower $editor]
if {[cequal $editor "xtex"] && [info exists editwin] && [winfo exists $editwin]} {
while {[Qmodflag]} {
set retval [DisplayQuest "Warning!!!\n\nData in editor window\nhas not been saved!\n\nDo you want to save it now?\nFile:\n $editinfname" \
"$boldl_font" "Save" "Save As" "Don't save" "Return to editor"]
switch $retval {
1 { SaveFile "" }
2 { SaveFile "AS" }
3 { break }
4 { return }
}
}
destroy $editwin
}
#*** Check if filename makes sense
switch $fname {
"\n" { set fname [FileSelBox OPENCREATE]
if {[cequal $fname ""]} {return}
}
default {}
}
#*** Append filename to ReOpen menu if filename is not there yet
if {![info exists editfilelist]} {set editfilelist ""}
if {$editor=="xtex"} {
XTeXEdit
} else {
global command_editor_$editor
eval set command \$command_editor_$editor
while {1} {
set pos [string first ":" "$command"]
if {$pos==-1} {break}
set sstr [expr {$pos ? [crange "$command" 0 "$pos-1" ] : ""}]
set estr [crange "$command" "$pos+1" end]
set mstr [string tolower [ctoken estr " .,:"]]
if {[cequal "$mstr" "fnamewoext"]} {
set mstr [strip_extension $fname]
set filenameneeded 1
}
if {[cequal "$mstr" "fname"]} {
set mstr $fname
set filenameneeded 1
}
set command [format "%s%s%s" "$sstr" "$mstr" "$estr"]
}
eval exec $command &
}
}
#******************************************************************************
#*** Quit was selected. Are the files saved ? *********************************
#******************************************************************************
proc EndXTeXEdit {} {
global boldl_font
global editwin editfname editinfname editmdfied
if {[info exists editwin] && [winfo exists $editwin]} {
while {[Qmodflag]} {
set retval [DisplayQuest "Warning!!!\n\nData in editor window\nhas not been saved!\n\nDo you want to save it now?\nFile:\n $editinfname" \
"$boldl_font" "Save" "Save As" "Really Quit"]
switch $retval {
1 { SaveFile "" }
2 { SaveFile "AS" }
3 { break;}
}
}
destroy $editwin
set editfname ""
}
}