1#!/bin/sh 2#\ 3exec wish8.4 "$0" 4# ====================================================================== 5# Simple text editor built with [incr Widgets] 6# ---------------------------------------------------------------------- 7# AUTHOR: Michael J. McLennan 8# CLASS: Object-Oriented Programming with [incr Tcl] 9# ====================================================================== 10package require Iwidgets 4.0 11 12option add *edit.width 5i startupFile 13option add *edit.height 4i startupFile 14option add *Fileselectiondialog.width 4i startupFile 15option add *Fileselectiondialog.height 5i startupFile 16 17# ---------------------------------------------------------------------- 18set FileWindows 0 19 20# ---------------------------------------------------------------------- 21# Dialog boxes 22# ---------------------------------------------------------------------- 23iwidgets::messagedialog .notice -title "itkedit: Notice" \ 24 -bitmap info -buttonboxpos e -modality application 25.notice hide OK 26.notice hide Help 27.notice buttonconfigure Cancel -text "Dismiss" 28 29iwidgets::messagedialog .confirm -title "itkedit: Confirm" \ 30 -bitmap questhead -modality application 31.confirm hide Help 32.confirm buttonconfigure OK -text "Yes" 33.confirm buttonconfigure Cancel -text "No" 34 35iwidgets::fileselectiondialog .files -title "itkedit: Files" \ 36 -childsitepos s -modality application 37.files hide Help 38 39set PaneMenu "[.files childsite].panes" 40iwidgets::optionmenu $PaneMenu -labeltext "Edit Window:" 41pack $PaneMenu -pady 6 42 43# ---------------------------------------------------------------------- 44# USAGE: file_load 45# 46# Initiates the process of loading a new text file for editing. 47# Pops up a Fileselectiondialog, allowing the user to select a 48# file for editing. If the user pushes the "load" button, the 49# file is loaded. 50# ---------------------------------------------------------------------- 51proc file_load {} { 52 global FileName PaneMenu 53 54 .files buttonconfigure OK -text "Load" 55 if {[.files activate]} { 56 set fname [.files get] 57 set cmd { 58 set fid [open $fname r] 59 set text [read $fid] 60 close $fid 61 } 62 if {[catch $cmd err] != 0} { 63 .notice configure -bitmap error \ 64 -text "Cannot load file \"$fname\":\n$err" 65 .notice activate 66 return 67 } 68 69 set pane [$PaneMenu get] 70 set win [.edit childsite $pane] 71 clear_text $win 72 $win.text insert end $text 73 $win.text configure -labeltext "file: $fname" 74 75 set FileName($win) $fname 76 } 77} 78 79# ---------------------------------------------------------------------- 80# USAGE: file_save_as 81# 82# Initiates the process of saving the current text into a particular 83# file. Pops up a Fileselectiondialog, allowing the user to select 84# a file for saving. If the user pushes the "save" button, the 85# file is saved. 86# ---------------------------------------------------------------------- 87proc file_save_as {} { 88 global FileName PaneMenu 89 90 .files buttonconfigure OK -text "Save" 91 if {[.files activate]} { 92 set pane [$PaneMenu get] 93 set win [.edit childsite $pane] 94 95 set FileName($win) [.files get] 96 97 file_save $win 98 } 99} 100 101# ---------------------------------------------------------------------- 102# USAGE: file_save <win> 103# 104# Saves the context of <win> into its associated file. Does the 105# dirty work to finish the file_save_as operation. 106# ---------------------------------------------------------------------- 107proc file_save {win} { 108 global FileName FileChanged 109 110 set cmd { 111 set fid [open $FileName($win) w] 112 puts $fid [$win.text get 1.0 end] 113 close $fid 114 set FileChanged($win) 0 115 $win.text configure -labeltext "file: $FileName($win)" 116 } 117 if {[catch $cmd err] != 0} { 118 .notice configure -bitmap error \ 119 -text "Cannot save file \"$FileName($win)\":\n$err" 120 .notice activate 121 } 122} 123 124# ---------------------------------------------------------------------- 125# USAGE: clear_text ?<win>? 126# 127# Clears the text area associated with <win>, making sure to save 128# any pending changes. If no <win> is specified, then all text 129# areas are cleared. 130# ---------------------------------------------------------------------- 131proc clear_text {{areas ""}} { 132 global FileName FileChanged FileWindows 133 134 if {$areas == ""} { 135 for {set i 0} {$i < $FileWindows} {incr i} { 136 set pane "area #[expr $i+1]" 137 lappend areas [.edit childsite $pane] 138 } 139 } 140 141 foreach win $areas { 142 if {$FileChanged($win)} { 143 set fname [file tail $FileName($win)] 144 .confirm configure -text "File \"$fname\" has changed.\nSave changes?" 145 if {[.confirm activate]} { 146 file_save $win 147 } 148 } 149 $win.text delete 1.0 end 150 set FileChanged($win) 0 151 } 152} 153 154# ---------------------------------------------------------------------- 155# USAGE: split_view 156# 157# Adds another editing pane to the current editor. 158# ---------------------------------------------------------------------- 159proc split_view {} { 160 global FileName FileChanged FileWindows PaneMenu 161 162 set pane "area #[incr FileWindows]" 163 .edit add $pane -minimum 100 164 $PaneMenu insert end $pane 165 166 set win [.edit childsite $pane] 167 168 set FileName($win) untitled.txt 169 set FileChanged($win) 0 170 171 iwidgets::scrolledtext $win.text -wrap none -labeltext "file: $FileName($win)" \ 172 -hscrollmode none -vscrollmode dynamic -visibleitems 1x1 173 pack $win.text -expand yes -fill both 174 175 bind [$win.text component text] <KeyPress> " 176 set FileChanged($win) 1 177 " 178} 179 180frame .mbar -borderwidth 2 -relief raised 181pack .mbar -side top -fill x 182 183# ---------------------------------------------------------------------- 184# FILE menu 185# ---------------------------------------------------------------------- 186menubutton .mbar.file -text "File" -underline 0 -menu .mbar.file.menu 187pack .mbar.file -side left -padx 4 188 189menu .mbar.file.menu 190.mbar.file.menu add command -label "Load..." \ 191 -accelerator " ^L" -underline 0 -command file_load 192bind . <Control-KeyPress-l> { .mbar.file.menu invoke "Load..." } 193 194.mbar.file.menu add command -label "Save As..." \ 195 -accelerator " ^S" -underline 0 -command file_save_as 196bind . <Control-KeyPress-s> { .mbar.file.menu invoke "Save As..." } 197 198.mbar.file.menu add separator 199.mbar.file.menu add command -label "Quit" \ 200 -accelerator " ^Q" -underline 0 -command {clear_text; exit} 201bind . <Control-KeyPress-q> { .mbar.file.menu invoke Quit } 202 203# ---------------------------------------------------------------------- 204# VIEW menu 205# ---------------------------------------------------------------------- 206menubutton .mbar.view -text "View" -underline 0 -menu .mbar.view.menu 207pack .mbar.view -side left -padx 4 208 209menu .mbar.view.menu 210.mbar.view.menu add command -label "Split" \ 211 -underline 0 -command split_view 212 213# ---------------------------------------------------------------------- 214# Editor 215# ---------------------------------------------------------------------- 216iwidgets::panedwindow .edit -orient horizontal 217pack .edit -expand yes -fill both 218 219split_view 220 221wm title . "itkedit" 222wm protocol . WM_DELETE_WINDOW { .mbar.file.menu invoke Quit } 223 224after idle { 225 update idletasks 226 wm minsize . [winfo reqwidth .] [winfo reqheight .] 227} 228 229 230