D. McC: I've been working on some "wee" apps for some time now. The most developed one is WISH Supernotepad 1.2, a simple text and HTML editor <http://www.geocities.com/pa_mcclamrock/supernotepad-2006-ez.tar.gz >. In modified or unmodified form, it might serve the purpose of a "weeEdit." The program script, uncompressed, takes up slightly less than 100 KB. (The WISH acronym, originally derived from the wish interpreter, now stands for Wee Integrated Suite of Helpers, although the "integrated" aspect still needs some work.)
Larry Smith The Wee project (aka the "We" project from Eolas) has not been static, but I have not had much time to work on it. I have integrated supernotepad, a browser (plume), a chat program, draw and paint programs, a notepad, two calculators - a four-banger and the IQ-15 from HP Calculator Simulations, and the tk# spreadsheet. The window manager is much improved, but there are a few more bugs to squash in order to get to a stable release. Eolas's Mike Doyle (MDD) has been funding this.
I'm a home computer user and hobbyist who developed the various functions of WISH Supernotepad because I, or members of my family, needed or wanted them. It was designed to run on Linux, but no doubt it could be made to work on other operating systems (with a bit of assistance from people who know more than I do about those systems). The code is intended to be comprehensible, well organized, and easily modified. Here are some things it can do; let's see if anyone wants to compare them with things they think a "weeEdit" should or shouldn't do.
Zipguy 2014-01-24 - You can find out my email address by clicking on Zipguy.
In case you just wondered what it looked like, I just added a screenshot of this program called weeEdit. This is what it looks like:
It only had one problem with Windows 7, which was at line number 2762, which was in the special characters section. I commented it out, and it ran just fine.
and here's the program.
#!/usr/bin/env wish # WISH Supernotepad 2006 # (the ninth version of WISH Supernotepad) # by David McClamrock <[email protected]> # based on Tk NotePad 0.5.0 by Joseph Acosta # and "textedit.tcl" by Eric Foster-Johnson # with help from Eric Foster-Johnson, # Graphical Applications with Tcl & Tk (2nd edition) # and Christopher Nelson, Tcl/Tk Programmer's Reference # Copyright ?2001-2006 David H. McClamrock # Freely available under Maximum Use License for Everyone # You should have received a copy of this license with this program. # If you didn't, e-mail the author to get one. ### INITIALIZATION ### # WISH applications require at least Tcl and Tk 8.4: set version "2006" set packtype regular set tclo [package require Tcl] set tko [package require Tk] if {$tclo < 8.4 || $tko < 8.4} { tk_messageBox -message "WISH Supernotepad requires at least version 8.4\ of Tcl and Tk" -type ok exit } # Setup for Starkit or regular filesystem: if {$packtype eq "starkit"} { package provide app-supernotepad $version set docdir [file join $starkit::topdir doc] set libdir [file join $starkit::topdir lib] } else { # Default settings: set docdir /usr/local/doc/wishes set libdir /usr/local/lib/wishes # May be altered by root's config file: set hardfig [file join / root wishes] if {[file isdirectory $hardfig]} { set locfig [file join $hardfig comdirs.tcl] if {[file readable $locfig]} { source $locfig } } } # One or more features may work only on unix platforms (including Linux), # so identify the platform: set platform [split [array get tcl_platform] ] if {[lsearch $platform unix] != -1} { set platform unix } # Make directory for configuration, etc., if it isn't there already: set wishdir [file join $env(HOME) wishes] if {[file isdirectory $wishdir] == 0} { file mkdir $wishdir } # Get lists of recently opened or inserted files, # and recently cut or copied blocks of text: set rece [file join $wishdir superece.tcl] set superpaste [file join $wishdir superpaste.tcl] if {[file readable $rece]} { source $rece } else { set recentlist [list] set reclim 1000 } if {[file readable $superpaste]} { source $superpaste } else { set pastelist [list] set pastelim 1000 } # Set some defaults (may be changed by configuration file--see below): set currentfile "" ; # No name for open file yet set addfile "" ; # No name for file to add, either set curprint "" ; # Nor a name for file to print set backfile "" ; # And no name for backup file set openins Open ; # By default, open rather than insert file set openew 0 ; # At first, don't open file in new window set converto 0 ; # Don't convert existing text to HTML unless told to do it set tabno 0 ; # No tabs have yet been automatically inserted set dumpfile "" ; # Don't trash old name of file that hasn't yet been renamed set filetosave none ; # Don't save a file when you haven't done anything set texwid 80 ; # Width of text widget set formawid 80 ; # Width of text formatted with newlines set texhi 32 ; # Height of text widget set wordwrap word ; # Word wrap on by default set fonto "lucidatypewriter" ; # Default font set siz 14 ; # Font size set helpfont "times" ; # User Help Guide font set helpsiz 14 ; # User Help Guide font size set fontaine [list $fonto $siz] ; # Default font with size set helpall [list $helpfont $helpsiz] ; # User Help Guide font with size set reunito 0 ; # Replace needless newlines (if desired) with spaces set parsep 1 ; # Keep paragraphs separate when omitting needless newlines set expert 0 ; # Don't do expert search with regular expressions set headsize 1 ; # size of HTML heading set html_fontsize 0 ; # Default regular HTML font size set listtype 1 ; # Use 1-2-3 numbering in HTML list set autotab 1 ; # Auto-tab to write Tcl code set palmdir "" ; # Directory to search for Palm Doc files set t .tx ; # Global variable for text widget set linkup 0 ; # Don't display Link-Text unless told to set linklist [list] ; # Nothing yet in list of Link-Text links # Read configuration file, if there is one: set superfig [file join $wishdir superfig.tcl] if {[file readable $superfig]} { source $superfig } # Use WISH Color Picker Plus for color configuration # (It sets color variables with default values; # values may then be changed by configuration files): # WISH Color Picker Plus (wishcolorplus.tcl) # Megawidget and related code for color configuration # in Tcl/Tk applications # by David McClamrock <[email protected]> # Copyright ?2002-2005 David H. McClamrock # (Pre-2005 versions were incorporated in WISH Supernotepad) # Freely available under Maximum Use License for Everyone # You should have received a copy of this license with this file. # If you didn't, e-mail the author to get one. ### List color names and values: ### set colorlist [list \ {255 250 250 snow} \ {248 248 255 GhostWhite} \ {245 245 245 WhiteSmoke} \ {220 220 220 gainsboro} \ {255 250 240 FloralWhite} \ {253 245 230 OldLace} \ {250 240 230 linen} \ {250 235 215 AntiqueWhite} \ {255 239 213 PapayaWhip} \ {255 235 205 BlanchedAlmond} \ {255 228 196 bisque} \ {255 218 185 PeachPuff} \ {255 222 173 NavajoWhite} \ {255 228 181 moccasin} \ {255 248 220 cornsilk} \ {255 255 240 ivory} \ {255 250 205 LemonChiffon} \ {255 245 238 seashell} \ {240 255 240 honeydew} \ {245 255 250 MintCream} \ {240 255 255 azure} \ {240 248 255 AliceBlue} \ {230 230 250 lavender} \ {255 240 245 LavenderBlush} \ {255 228 225 MistyRose} \ {255 255 255 white} \ {0 0 0 black} \ {47 79 79 DarkSlateGray} \ {105 105 105 DimGray} \ {112 128 144 SlateGray} \ {119 136 153 LightSlateGray} \ {190 190 190 gray} \ {211 211 211 LightGray} \ {25 25 112 MidnightBlue} \ {0 0 128 NavyBlue} \ {100 149 237 CornflowerBlue} \ {72 61 139 DarkSlateBlue} \ {106 90 205 SlateBlue} \ {123 104 238 MediumSlateBlue} \ {132 112 255 LightSlateBlue} \ {0 0 205 MediumBlue} \ {65 105 225 RoyalBlue} \ {0 0 255 blue} \ {30 144 255 DodgerBlue} \ {0 191 255 DeepSkyBlue} \ {135 206 235 SkyBlue} \ {135 206 250 LightSkyBlue} \ {70 130 180 SteelBlue} \ {176 196 222 LightSteelBlue} \ {173 216 230 LightBlue} \ {176 224 230 PowderBlue} \ {175 238 238 PaleTurquoise} \ {0 206 209 DarkTurquoise} \ {72 209 204 MediumTurquoise} \ {64 224 208 turquoise} \ {0 255 255 cyan} \ {224 255 255 LightCyan} \ {95 158 160 CadetBlue} \ {102 205 170 MediumAquamarine} \ {127 255 212 aquamarine} \ {0 100 0 DarkGreen} \ {85 107 47 DarkOliveGreen} \ {143 188 143 DarkSeaGreen} \ {46 139 87 SeaGreen} \ {60 179 113 MediumSeaGreen} \ {32 178 170 LightSeaGreen} \ {152 251 152 PaleGreen} \ {0 255 127 SpringGreen} \ {124 252 0 LawnGreen} \ {0 255 0 green} \ {127 255 0 chartreuse} \ {0 250 154 MediumSpringGreen} \ {173 255 47 GreenYellow} \ {50 205 50 LimeGreen} \ {154 205 50 YellowGreen} \ {34 139 34 ForestGreen} \ {107 142 35 OliveDrab} \ {189 183 107 DarkKhaki} \ {240 230 140 khaki} \ {238 232 170 PaleGoldenrod} \ {250 250 210 LightGoldenrodYellow} \ {255 255 224 LightYellow} \ {255 255 0 yellow} \ {255 215 0 gold} \ {238 221 130 LightGoldenrod} \ {218 165 32 goldenrod} \ {184 134 11 DarkGoldenrod} \ {188 143 143 RosyBrown} \ {205 92 92 IndianRed} \ {139 69 19 SaddleBrown} \ {160 82 45 sienna} \ {205 133 63 peru} \ {222 184 135 burlywood} \ {245 245 220 beige} \ {245 222 179 wheat} \ {244 164 96 SandyBrown} \ {210 180 140 tan} \ {210 105 30 chocolate} \ {178 34 34 firebrick} \ {165 42 42 brown} \ {233 150 122 DarkSalmon} \ {250 128 114 salmon} \ {255 160 122 LightSalmon} \ {255 165 0 orange} \ {255 140 0 DarkOrange} \ {255 127 80 coral} \ {240 128 128 LightCoral} \ {255 99 71 tomato} \ {255 69 0 OrangeRed} \ {255 0 0 red} \ {255 105 180 HotPink} \ {255 20 147 DeepPink} \ {255 192 203 pink} \ {255 182 193 LightPink} \ {219 112 147 PaleVioletRed} \ {176 48 96 maroon} \ {199 21 133 MediumVioletRed} \ {208 32 144 VioletRed} \ {255 0 255 magenta} \ {238 130 238 violet} \ {221 160 221 plum} \ {218 112 214 orchid} \ {186 85 211 MediumOrchid} \ {153 50 204 DarkOrchid} \ {148 0 211 DarkViolet} \ {138 43 226 BlueViolet} \ {160 32 240 purple} \ {147 112 219 MediumPurple} \ {216 191 216 thistle} \ {255 250 250 snow1} \ {238 233 233 snow2} \ {205 201 201 snow3} \ {139 137 137 snow4} \ {255 245 238 seashell1} \ {238 229 222 seashell2} \ {205 197 191 seashell3} \ {139 134 130 seashell4} \ {255 239 219 AntiqueWhite1} \ {238 223 204 AntiqueWhite2} \ {205 192 176 AntiqueWhite3} \ {139 131 120 AntiqueWhite4} \ {255 228 196 bisque1} \ {238 213 183 bisque2} \ {205 183 158 bisque3} \ {139 125 107 bisque4} \ {255 218 185 PeachPuff1} \ {238 203 173 PeachPuff2} \ {205 175 149 PeachPuff3} \ {139 119 101 PeachPuff4} \ {255 222 173 NavajoWhite1} \ {238 207 161 NavajoWhite2} \ {205 179 139 NavajoWhite3} \ {139 121 94 NavajoWhite4} \ {255 250 205 LemonChiffon1} \ {238 233 191 LemonChiffon2} \ {205 201 165 LemonChiffon3} \ {139 137 112 LemonChiffon4} \ {255 248 220 cornsilk1} \ {238 232 205 cornsilk2} \ {205 200 177 cornsilk3} \ {139 136 120 cornsilk4} \ {255 255 240 ivory1} \ {238 238 224 ivory2} \ {205 205 193 ivory3} \ {139 139 131 ivory4} \ {240 255 240 honeydew1} \ {224 238 224 honeydew2} \ {193 205 193 honeydew3} \ {131 139 131 honeydew4} \ {255 240 245 LavenderBlush1} \ {238 224 229 LavenderBlush2} \ {205 193 197 LavenderBlush3} \ {139 131 134 LavenderBlush4} \ {255 228 225 MistyRose1} \ {238 213 210 MistyRose2} \ {205 183 181 MistyRose3} \ {139 125 123 MistyRose4} \ {240 255 255 azure1} \ {224 238 238 azure2} \ {193 205 205 azure3} \ {131 139 139 azure4} \ {131 111 255 SlateBlue1} \ {122 103 238 SlateBlue2} \ {105 89 205 SlateBlue3} \ {71 60 139 SlateBlue4} \ {72 118 255 RoyalBlue1} \ {67 110 238 RoyalBlue2} \ {58 95 205 RoyalBlue3} \ {39 64 139 RoyalBlue4} \ {0 0 255 blue1} \ {0 0 238 blue2} \ {0 0 205 blue3} \ {0 0 139 blue4} \ {30 144 255 DodgerBlue1} \ {28 134 238 DodgerBlue2} \ {24 116 205 DodgerBlue3} \ {16 78 139 DodgerBlue4} \ {99 184 255 SteelBlue1} \ {92 172 238 SteelBlue2} \ {79 148 205 SteelBlue3} \ {54 100 139 SteelBlue4} \ {0 191 255 DeepSkyBlue1} \ {0 178 238 DeepSkyBlue2} \ {0 154 205 DeepSkyBlue3} \ {0 104 139 DeepSkyBlue4} \ {135 206 255 SkyBlue1} \ {126 192 238 SkyBlue2} \ {108 166 205 SkyBlue3} \ {74 112 139 SkyBlue4} \ {176 226 255 LightSkyBlue1} \ {164 211 238 LightSkyBlue2} \ {141 182 205 LightSkyBlue3} \ {96 123 139 LightSkyBlue4} \ {198 226 255 SlateGray1} \ {185 211 238 SlateGray2} \ {159 182 205 SlateGray3} \ {108 123 139 SlateGray4} \ {202 225 255 LightSteelBlue1} \ {188 210 238 LightSteelBlue2} \ {162 181 205 LightSteelBlue3} \ {110 123 139 LightSteelBlue4} \ {191 239 255 LightBlue1} \ {178 223 238 LightBlue2} \ {154 192 205 LightBlue3} \ {104 131 139 LightBlue4} \ {224 255 255 LightCyan1} \ {209 238 238 LightCyan2} \ {180 205 205 LightCyan3} \ {122 139 139 LightCyan4} \ {187 255 255 PaleTurquoise1} \ {174 238 238 PaleTurquoise2} \ {150 205 205 PaleTurquoise3} \ {102 139 139 PaleTurquoise4} \ {152 245 255 CadetBlue1} \ {142 229 238 CadetBlue2} \ {122 197 205 CadetBlue3} \ {83 134 139 CadetBlue4} \ {0 245 255 turquoise1} \ {0 229 238 turquoise2} \ {0 197 205 turquoise3} \ {0 134 139 turquoise4} \ {0 255 255 cyan1} \ {0 238 238 cyan2} \ {0 205 205 cyan3} \ {0 139 139 cyan4} \ {151 255 255 DarkSlateGray1} \ {141 238 238 DarkSlateGray2} \ {121 205 205 DarkSlateGray3} \ {82 139 139 DarkSlateGray4} \ {127 255 212 aquamarine1} \ {118 238 198 aquamarine2} \ {102 205 170 aquamarine3} \ {69 139 116 aquamarine4} \ {193 255 193 DarkSeaGreen1} \ {180 238 180 DarkSeaGreen2} \ {155 205 155 DarkSeaGreen3} \ {105 139 105 DarkSeaGreen4} \ {84 255 159 SeaGreen1} \ {78 238 148 SeaGreen2} \ {67 205 128 SeaGreen3} \ {46 139 87 SeaGreen4} \ {154 255 154 PaleGreen1} \ {144 238 144 PaleGreen2} \ {124 205 124 PaleGreen3} \ {84 139 84 PaleGreen4} \ {0 255 127 SpringGreen1} \ {0 238 118 SpringGreen2} \ {0 205 102 SpringGreen3} \ {0 139 69 SpringGreen4} \ {0 255 0 green1} \ {0 238 0 green2} \ {0 205 0 green3} \ {0 139 0 green4} \ {127 255 0 chartreuse1} \ {118 238 0 chartreuse2} \ {102 205 0 chartreuse3} \ {69 139 0 chartreuse4} \ {192 255 62 OliveDrab1} \ {179 238 58 OliveDrab2} \ {154 205 50 OliveDrab3} \ {105 139 34 OliveDrab4} \ {202 255 112 DarkOliveGreen1} \ {188 238 104 DarkOliveGreen2} \ {162 205 90 DarkOliveGreen3} \ {110 139 61 DarkOliveGreen4} \ {255 246 143 khaki1} \ {238 230 133 khaki2} \ {205 198 115 khaki3} \ {139 134 78 khaki4} \ {255 236 139 LightGoldenrod1} \ {238 220 130 LightGoldenrod2} \ {205 190 112 LightGoldenrod3} \ {139 129 76 LightGoldenrod4} \ {255 255 224 LightYellow1} \ {238 238 209 LightYellow2} \ {205 205 180 LightYellow3} \ {139 139 122 LightYellow4} \ {255 255 0 yellow1} \ {238 238 0 yellow2} \ {205 205 0 yellow3} \ {139 139 0 yellow4} \ {255 215 0 gold1} \ {238 201 0 gold2} \ {205 173 0 gold3} \ {139 117 0 gold4} \ {255 193 37 goldenrod1} \ {238 180 34 goldenrod2} \ {205 155 29 goldenrod3} \ {139 105 20 goldenrod4} \ {255 185 15 DarkGoldenrod1} \ {238 173 14 DarkGoldenrod2} \ {205 149 12 DarkGoldenrod3} \ {139 101 8 DarkGoldenrod4} \ {255 193 193 RosyBrown1} \ {238 180 180 RosyBrown2} \ {205 155 155 RosyBrown3} \ {139 105 105 RosyBrown4} \ {255 106 106 IndianRed1} \ {238 99 99 IndianRed2} \ {205 85 85 IndianRed3} \ {139 58 58 IndianRed4} \ {255 130 71 sienna1} \ {238 121 66 sienna2} \ {205 104 57 sienna3} \ {139 71 38 sienna4} \ {255 211 155 burlywood1} \ {238 197 145 burlywood2} \ {205 170 125 burlywood3} \ {139 115 85 burlywood4} \ {255 231 186 wheat1} \ {238 216 174 wheat2} \ {205 186 150 wheat3} \ {139 126 102 wheat4} \ {255 165 79 tan1} \ {238 154 73 tan2} \ {205 133 63 tan3} \ {139 90 43 tan4} \ {255 127 36 chocolate1} \ {238 118 33 chocolate2} \ {205 102 29 chocolate3} \ {139 69 19 chocolate4} \ {255 48 48 firebrick1} \ {238 44 44 firebrick2} \ {205 38 38 firebrick3} \ {139 26 26 firebrick4} \ {255 64 64 brown1} \ {238 59 59 brown2} \ {205 51 51 brown3} \ {139 35 35 brown4} \ {255 140 105 salmon1} \ {238 130 98 salmon2} \ {205 112 84 salmon3} \ {139 76 57 salmon4} \ {255 160 122 LightSalmon1} \ {238 149 114 LightSalmon2} \ {205 129 98 LightSalmon3} \ {139 87 66 LightSalmon4} \ {255 165 0 orange1} \ {238 154 0 orange2} \ {205 133 0 orange3} \ {139 90 0 orange4} \ {255 127 0 DarkOrange1} \ {238 118 0 DarkOrange2} \ {205 102 0 DarkOrange3} \ {139 69 0 DarkOrange4} \ {255 114 86 coral1} \ {238 106 80 coral2} \ {205 91 69 coral3} \ {139 62 47 coral4} \ {255 99 71 tomato1} \ {238 92 66 tomato2} \ {205 79 57 tomato3} \ {139 54 38 tomato4} \ {255 69 0 OrangeRed1} \ {238 64 0 OrangeRed2} \ {205 55 0 OrangeRed3} \ {139 37 0 OrangeRed4} \ {255 0 0 red1} \ {238 0 0 red2} \ {205 0 0 red3} \ {139 0 0 red4} \ {255 20 147 DeepPink1} \ {238 18 137 DeepPink2} \ {205 16 118 DeepPink3} \ {139 10 80 DeepPink4} \ {255 110 180 HotPink1} \ {238 106 167 HotPink2} \ {205 96 144 HotPink3} \ {139 58 98 HotPink4} \ {255 181 197 pink1} \ {238 169 184 pink2} \ {205 145 158 pink3} \ {139 99 108 pink4} \ {255 174 185 LightPink1} \ {238 162 173 LightPink2} \ {205 140 149 LightPink3} \ {139 95 101 LightPink4} \ {255 130 171 PaleVioletRed1} \ {238 121 159 PaleVioletRed2} \ {205 104 137 PaleVioletRed3} \ {139 71 93 PaleVioletRed4} \ {255 52 179 maroon1} \ {238 48 167 maroon2} \ {205 41 144 maroon3} \ {139 28 98 maroon4} \ {255 62 150 VioletRed1} \ {238 58 140 VioletRed2} \ {205 50 120 VioletRed3} \ {139 34 82 VioletRed4} \ {255 0 255 magenta1} \ {238 0 238 magenta2} \ {205 0 205 magenta3} \ {139 0 139 magenta4} \ {255 131 250 orchid1} \ {238 122 233 orchid2} \ {205 105 201 orchid3} \ {139 71 137 orchid4} \ {255 187 255 plum1} \ {238 174 238 plum2} \ {205 150 205 plum3} \ {139 102 139 plum4} \ {224 102 255 MediumOrchid1} \ {209 95 238 MediumOrchid2} \ {180 82 205 MediumOrchid3} \ {122 55 139 MediumOrchid4} \ {191 62 255 DarkOrchid1} \ {178 58 238 DarkOrchid2} \ {154 50 205 DarkOrchid3} \ {104 34 139 DarkOrchid4} \ {155 48 255 purple1} \ {145 44 238 purple2} \ {125 38 205 purple3} \ {85 26 139 purple4} \ {171 130 255 MediumPurple1} \ {159 121 238 MediumPurple2} \ {137 104 205 MediumPurple3} \ {93 71 139 MediumPurple4} \ {255 225 255 thistle1} \ {238 210 238 thistle2} \ {205 181 205 thistle3} \ {139 123 139 thistle4} \ {169 169 169 DarkGray} \ {0 0 139 DarkBlue} \ {0 139 139 DarkCyan} \ {139 0 139 DarkMagenta} \ {139 0 0 DarkRed} \ {144 238 144 LightGreen}] set colorlist [lsort -dictionary -index end $colorlist] ### Initialize directories and settings: ### # Where program listings and configuration files go: set wishdir [file join $env(HOME) .wishes] set oldwishdir [file join $env(HOME) wishes] if {[file isdirectory $wishdir] == 0} { if {[file isdirectory $oldwishdir]} { file link $wishdir $oldwishdir set wishdir $oldwishdir } else { file mkdir $wishdir } } # Where color schemes come from: set schemedir [file join $wishdir colorschemes] set sampledir [file join $libdir colorschemes] ; # App sets variable "libdir" if {[file isdirectory $schemedir] == 0} { catch {file copy $sampledir $schemedir} } # Default color settings for WISH applications # (may be changed by configuration files) set winback bisque ; # Window background set winfore black ; # Window foreground set selback cyan ; # Selection background set selfore black ; # Selection foreground set buttback bisque ; # Regular button background set buttfore black ; # Regular button foreground set miniback "#FFD0A0" ; # Mini-toolbar button background set minifore black ; # Mini-toolbar button foreground set listback "#FFFFF0" ; # Listbox background set listfore black ; # Listbox foreground set textback white ; # Text widget background set textfore black ; # Text widget foreground set inacback "#40E4FF" ; # Inactive selection background set linktex blue ; # Link text color set entback "#FFFFF0" ; # Entry widget background set entfore black ; # Entry widget foreground set headback "#FFC080" ; # Emphasized label background set headfore black ; # Emphasized label foreground set lightback "#FFF0E4" ; # Light label background set lightfore black ; # Light label foreground # Selection color for checkbuttons and radiobuttons is # different in Tk 8.5 than in 8.4: set newsel white ; # Tk 8.5 set oldsel blue ; # Tk 8.4 set tko [package require Tk] if {$tko > 8.4} { set regradio $newsel } else { set regradio $oldsel } set whatbutt "" ; # Nothing selected to configure yet tk_setPalette background $winback foreground $winfore \ selectBackground $selback selectForeground $selfore # Lists of widgets to configure # (applications should add their own widgets # after sourcing wishcolorplus.tcl): set buttlist [list .colo.pickapply .colo.schemapply \ .colo.schemedel .colo.ok .colo.close] ; # Buttons set minilist [list .colo.schemename] ; # Use this to show mini-toolbar color set lublist [list .colo.list .colo.schemelist] ; # Listboxes set texlist [list .colo.tx] ; # Text widgets set entlist [list .colo.ent] ; # Entry widgets set regradiolist [list] ; # No regular radiobuttons or checkbuttons here set spinlist [list] ; # Nor spinboxes # Alternating radiobuttons: set headlist [list .colo.winfad .colo.selfad \ .colo.buttfad .colo.minifad .colo.listfad .colo.textfad \ .colo.linkup .colo.entfad .colo.headfad .colo.lightfad ] set lightlist [list .colo.winbad .colo.selbad \ .colo.buttbad .colo.minibad .colo.listbad .colo.textbad \ .colo.inacbad .colo.entbad .colo.headbad .colo.lightbad] ### Procedure for setting up color selection box ### # RGB Color-setting Scale # from Graphical Applications with Tcl and Tk, 2nd edition, Chapter 3 # by Eric Foster-Johnson # modified by David McClamrock # Thanks to Ulrich Sch?? for suggesting that I add color names, # and for contributing some code! proc wishcolorplus {} { # Set variables for red, green, blue, color selected, # and hexadecimal code color; set background # (number 128 will be midpoint of color scale): global red green blue color hex colorlist showname appcolo toplevel .colo wm title .colo "WISH Color Picker Plus" tk_setPalette background $::winback foreground $::winfore \ selectBackground $::selback selectForeground $::selfore set red 255 set green 204 set blue 153 set color "" set showname nothing set hex black grid [label .colo.pick -text "Right-click or double left-click\ color name (or move sliders)" -pady 4 -background $::lightback \ -foreground $::lightfore] \ -row 0 -column 0 -columnspan 3 -sticky news # Sliding scale to change the amount of red: set scaleng 200 ; # Length of scales set scalwid 12 ; # Width of scales set slidleng 24 ; # Length of sliders grid [label .colo.reddo -text "Red : "] \ -row 1 -column 0 -sticky news grid [scale .colo.red -from 0 -to 255 -orient horizontal \ -length $scaleng -width $scalwid -sliderlength $slidleng \ -variable red -activebackground red -tickinterval 64 \ -command "modify_color red"] \ -row 1 -column 1 -sticky news # Same for green and blue: grid [label .colo.greeno -text "Green : "] \ -row 2 -column 0 -sticky news grid [scale .colo.green -from 0 -to 255 -orient horizontal \ -length $scaleng -width $scalwid -sliderlength $slidleng \ -variable green -activebackground green -tickinterval 64 \ -command "modify_color green"] \ -row 2 -column 1 -sticky news grid [label .colo.bluey -text "Blue : "] \ -row 3 -column 0 -sticky news grid [scale .colo.blue -from 0 -to 255 -orient horizontal \ -length $scaleng -width $scalwid -sliderlength $slidleng \ -variable blue -activebackground blue -tickinterval 64 \ -command "modify_color blue"] \ -row 3 -column 1 -sticky news foreach scala [list .colo.red .colo.green .colo.blue] { bind $scala <ButtonRelease-1> { catch {.colo.list selection clear 0 end} } } # Scrolling listbox for color names: frame .colo.lib listbox .colo.list -bg "#FFFFF0" -width 20 scrollbar .colo.rolly -width 12 -command ".colo.list yview" .colo.list configure -yscrollcommand ".colo.rolly set" pack .colo.list .colo.rolly -in .colo.lib \ -side left -expand 1 -fill both grid .colo.lib -row 1 -column 2 -rowspan 6 -sticky news foreach couleur $colorlist { .colo.list insert end [lindex $couleur end] } bind .colo.list <Double-Button-1> { set item [.colo.list curselection] set showname [.colo.list get $item] pickname $item } bind .colo.list <Button-3> { .colo.list selection clear 0 end set clixel %y set clickline [.colo.list nearest $clixel] .colo.list selection set $clickline $clickline set item [.colo.list curselection] set showname [.colo.list get $item] pickname $item } # Labeled button to show the color selected: grid [label .colo.pico -text "PICK: "] -row 4 -column 0 -sticky news grid [button .colo.color -textvariable color -border 4 -pady 4] \ -row 4 -column 1 -sticky news .colo.color configure -bg $::headback -fg $::headfore -command { $whatbutt configure -text $color after 10 {colorgrip $whatbutt} } # Color schemes: grid [button .colo.schemename -bg $::miniback -fg $::minifore \ -relief groove -pady 2 -border 3 -text "Name This Color Scheme: " \ -command name_scheme] -row 5 -column 0 -columnspan 2 -sticky news grid [entry .colo.schement -width 36 -bg $::entback \ -fg $::entfore -border 2 -exportselection 0] \ -row 6 -column 0 -columnspan 2 -sticky news frame .colo.flub listbox .colo.schemelist -width 36 -height 7 -bg $::listback \ -fg $::listfore -listvariable schemelist -selectmode single \ -exportselection 0 scrollbar .colo.schemeroll -width 12 -command ".colo.schemelist yview" .colo.schemelist configure -yscrollcommand ".colo.schemeroll set" pack .colo.schemelist .colo.schemeroll -in .colo.flub \ -side left -expand 1 -fill both grid .colo.flub -row 7 -column 0 -columnspan 2 -sticky news frame .colo.scutts button .colo.pickapply -text "Apply Picked Colors" -command { .colo.schemelist selection clear 0 end pickapply showcolo } button .colo.schemapply -text "Apply Color Scheme" \ -command apply_scheme button .colo.schemedel -text "Delete Color Scheme" \ -activebackground red -command delete_scheme button .colo.ok -text "OK" -command { savecolo $appcolo destroy .colo } button .colo.close -text "Close" -command {destroy .colo} foreach butt [list .colo.pickapply .colo.schemapply \ .colo.schemedel .colo.ok .colo.close] { $butt configure -border 1 -pady 0 -bg $::buttback -fg $::buttfore } pack .colo.pickapply .colo.schemapply .colo.schemedel .colo.ok \ .colo.close -in .colo.scutts -side top -expand 1 -fill both grid .colo.scutts -row 7 -column 2 -sticky news bind .colo.schement <Key-Return> name_scheme bind .colo.schemelist <Button-1> showschemename bind .colo.schemelist <Double-Button-1> apply_scheme bind .colo.schemelist <Button-3> { .colo.schemelist selection clear 0 end set clixel %y set clickline [.colo.schemelist nearest $clixel] .colo.schemelist selection set $clickline showschemename apply_scheme } focus .colo.schement getschemes # Color-selection radiobuttons and display buttons: grid [label .colo.choo -text "CHOOSE COLOR TO CHANGE" -bg $::headback \ -fg $::headfore] -row 0 -column 3 -columnspan 2 -sticky news frame .colo.fradio frame .colo.flabs radiobutton .colo.winbad -text "Window background : " \ -variable whatbutt -value ".colo.winback" button .colo.winback -bg $::winback -text $::winback radiobutton .colo.winfad -text "Window text : " \ -variable whatbutt -value ".colo.winfore" button .colo.winfore -bg $::winfore -text $::winfore radiobutton .colo.selbad -text "Selection background : " \ -variable whatbutt -value ".colo.selback" button .colo.selback -bg $::selback -text $::selback radiobutton .colo.selfad -text "Selected text : " \ -variable whatbutt -value ".colo.selfore" button .colo.selfore -bg $::selfore -text $::selfore radiobutton .colo.buttbad -text "Regular button background : " \ -variable whatbutt -value ".colo.buttback" button .colo.buttback -bg $::buttback -text $::buttback radiobutton .colo.buttfad -text "Regular button text : " \ -variable whatbutt -value ".colo.buttfore" button .colo.buttfore -bg $::buttfore -text $::buttfore radiobutton .colo.minibad -text "Mini-toolbar button background : " \ -variable whatbutt -value ".colo.miniback" button .colo.miniback -bg $::miniback -text $::miniback radiobutton .colo.minifad -text "Mini-toolbar button text : " \ -variable whatbutt -value ".colo.minifore" button .colo.minifore -bg $::minifore -text $::minifore radiobutton .colo.listbad -text "Listbox background : " \ -variable whatbutt -value ".colo.listback" button .colo.listback -bg $::listback -text $::listback radiobutton .colo.listfad -text "Listbox text : " \ -variable whatbutt -value ".colo.listfore" button .colo.listfore -bg $::listfore -text $::listfore radiobutton .colo.textbad -text "Multi-line textbox background : " \ -variable whatbutt -value ".colo.textback" button .colo.textback -bg $::textback -text $::textback radiobutton .colo.textfad -text "Multi-line textbox text : " \ -variable whatbutt -value ".colo.textfore" button .colo.textfore -bg $::textfore -text $::textfore radiobutton .colo.inacbad -text "Inactive selection background : " \ -variable whatbutt -value ".colo.inacback" button .colo.inacback -bg $::inacback -text $::inacback radiobutton .colo.linkup -text "Link text : " \ -variable whatbutt -value ".colo.linktex" button .colo.linktex -bg $::linktex -text $::linktex radiobutton .colo.entbad -text "Single-line entry background : " \ -variable whatbutt -value ".colo.entback" button .colo.entback -bg $::entback -text $::entback radiobutton .colo.entfad -text "Single-line entry text : " \ -variable whatbutt -value ".colo.entfore" button .colo.entfore -bg $::entfore -text $::entfore radiobutton .colo.headbad -text "Emphasized label background : " \ -variable whatbutt -value ".colo.headback" button .colo.headback -bg $::headback -text $::headback radiobutton .colo.headfad -text "Emphasized label text : " \ -variable whatbutt -value ".colo.headfore" button .colo.headfore -bg $::headfore -text $::headfore radiobutton .colo.lightbad -text "Light label background : " \ -variable whatbutt -value ".colo.lightback" button .colo.lightback -bg $::lightback -text $::lightback radiobutton .colo.lightfad -text "Light label text : " \ -variable whatbutt -value ".colo.lightfore" button .colo.lightfore -bg $::lightfore -text $::lightfore # Get each widget's color-display button ready # to transmit its color to others: foreach colorbutt [list .colo.winback .colo.winfore .colo.selback \ .colo.selfore .colo.buttback .colo.buttfore .colo.miniback \ .colo.minifore .colo.listback .colo.listfore .colo.textback \ .colo.textfore .colo.inacback .colo.linktex \ .colo.entback .colo.entfore .colo.headback .colo.headfore \ .colo.lightback .colo.lightfore] { colortext $colorbutt $colorbutt configure -pady 0 -border 0 bind $colorbutt <Button-1> { set mybutt %W $::whatbutt configure -text [$mybutt cget -text] after 10 {colorgrip $::whatbutt} } colorgrip $colorbutt } pack .colo.winbad .colo.winfad .colo.selbad .colo.selfad \ .colo.buttbad .colo.buttfad .colo.minibad .colo.minifad \ .colo.listbad .colo.listfad .colo.textbad .colo.textfad \ .colo.inacbad .colo.linkup .colo.entbad .colo.entfad \ .colo.headbad .colo.headfad .colo.lightbad .colo.lightfad \ -in .colo.fradio -side top -expand 1 -fill both pack .colo.winback .colo.winfore .colo.selback .colo.selfore \ .colo.buttback .colo.buttfore .colo.miniback .colo.minifore \ .colo.listback .colo.listfore .colo.textback .colo.textfore \ .colo.inacback .colo.linktex .colo.entback .colo.entfore \ .colo.headback .colo.headfore .colo.lightback .colo.lightfore \ -in .colo.flabs -side top -expand 1 -fill both grid .colo.fradio -row 1 -column 3 -rowspan 7 -sticky news grid .colo.flabs -row 1 -column 4 -rowspan 7 -sticky news frame .colo.tux text .colo.tx -bg $::textback -fg $::textfore -height 3 \ -font "lucidatypewriter 14" scrollbar .colo.tuxroll -width 12 -command ".colo.tx yview" .colo.tx configure -yscrollcommand ".colo.tuxroll set" pack .colo.tx .colo.tuxroll -in .colo.tux \ -side left -expand 1 -fill both grid .colo.tux -row 8 -column 0 -columnspan 5 -sticky news .colo.tx insert 1.0 "TEST TEXT HERE\nLinks look like this" .colo.tx tag configure linklike -foreground $::linktex -underline 1 .colo.tx tag add linklike 2.0 "2.0 lineend" # Make sure radiobutton and checkbutton colors are right: colorcheck } ### Color-selection procedures ### # Procedure to show color name in display button: proc colortext {butt} { global winback winfore selback selfore buttback buttfore miniback \ minifore listback listfore textback textfore inacback linktex \ entback entfore headback headfore lightback lightfore # A little quick trickery to get the variable names, # abusing "file extension" for buttons not files: set buttvar [string trimleft [file extension $butt] "."] $butt configure -text [set $buttvar] } # Procedure to display picked color in button: proc colorgrip {butt} { global colorlist set couleur [$butt cget -text] if {[string first "#" $couleur] < 0} { set listline [lsearch -regexp $colorlist "\\\W$couleur"] set reds [lindex $colorlist $listline 0] set greens [lindex $colorlist $listline 1] set blues [lindex $colorlist $listline 2] set couleur [format "#%2.2X%2.2X%2.2X" $reds $greens $blues] } set reds [string range $couleur 1 2] set greens [string range $couleur 3 4] set blues [string range $couleur 5 6] if {[expr 0x$reds + 0x$greens + 0x$blues < 480] && \ [expr 0x$greens < 180]} { $butt configure -fg white } else { $butt configure -fg black } $butt configure -bg $couleur } # Procedure to set new values for color variables # in preparation for applying new colors: proc pickapply {} { global winback winfore selback selfore buttback buttfore miniback \ minifore listback listfore textback textfore inacback linktex \ entback entfore headback headfore lightback lightfore foreach butt [list .colo.winback .colo.winfore .colo.selback \ .colo.selfore .colo.buttback .colo.buttfore .colo.miniback \ .colo.minifore .colo.listback .colo.listfore .colo.textback \ .colo.textfore .colo.inacback .colo.linktex .colo.entback \ .colo.entfore .colo.headback .colo.headfore .colo.lightback \ .colo.lightfore] { # There's that quick trickery again: set buttvar [string trimleft [file extension $butt] "."] set $buttvar [$butt cget -text] } } # Procedure for changing the color selected: proc modify_color {which_color value} { global color red green blue showname switch $which_color { red {set red $value} green {set green $value} blue {set blue $value} } if {[expr $red + $green + $blue < 480] && \ [expr $green < 180]} { set hex white } else { set hex black } if {$color ne $showname} { set color [format "#%2.2X%2.2X%2.2X" \ $red $green $blue] } .colo.color configure -background $color \ -foreground $hex } # Procedure for getting a color name selection # to make the sliders move and the color code change: proc pickname {item} { global color colorlist red green blue showname whatbutt set listline [lindex $colorlist $item] set red [lindex $listline 0] modify_color red $red set green [lindex $listline 1] modify_color green $green set blue [lindex $listline 2] modify_color blue $blue set color $showname set showname nothing } # Procedure to make sure radiobutton, checkbutton, \ # and label colors are right: proc colorcheck {} { # Labels, or radiobuttons with alternating label colors: foreach head $::headlist { if {[winfo exists $head]} { $head configure -background $::headback \ -foreground $::headfore } } foreach light $::lightlist { if {[winfo exists $light]} { $light configure -background $::lightback \ -foreground $::lightfore } } # Get more or less correct selection colors # for radiobuttons and checkbuttons: set ::newsel [.colo.winfore cget -fg] set ::oldsel $::winfore if {$::tko > 8.4} { set ::emphasel [.colo.headfore cget -fg] set ::lightsel [.colo.lightfore cget -fg] set ::regradio $::newsel } else { set ::emphasel $::headfore set ::lightsel $::lightfore set ::regradio $::oldsel } # Once more through the lists, to apply selection colors: foreach head $::headlist { if {[winfo exists $head] && [regexp \ {Radiobutton|Checkbutton} [winfo class $head]]} { $head configure -selectcolor $::emphasel } } foreach light $::lightlist { if {[winfo exists $light] && [regexp \ {Radiobutton|Checkbutton} [winfo class $light]]} { $light configure -selectcolor $::lightsel } } foreach reg $::regradiolist { if {[winfo exists $reg]} { $reg configure -selectcolor $::regradio } } } # Procedure to show new configuration: proc showcolo {} { global winback winfore selback selfore buttback buttfore miniback \ minifore listback listfore textback textfore inacback linktex \ entback entfore headback headfore lightback lightfore newsel oldsel\ buttlist minilist lublist texlist entlist headlist lightlist spinlist tk_setPalette background $winback foreground $winfore \ selectBackground $selback selectForeground $selfore if {[winfo exists .colo.pick]} { .colo.pick configure -bg $lightback -fg $lightfore } if {[winfo exists .colo.choo]} { .colo.choo configure -bg $headback -fg $headfore } foreach butt $buttlist { if {[winfo exists $butt]} { $butt configure -bg $buttback -fg $buttfore } } foreach mini $minilist { if {[winfo exists $mini]} { $mini configure -bg $miniback -fg $minifore } } foreach lub $lublist { if {[winfo exists $lub]} { $lub configure -bg $listback -fg $listfore } } foreach tex $texlist { if {[winfo exists $tex]} { $tex configure -bg $textback -fg $textfore $tex tag configure linklike -foreground $linktex -underline 1 if {$::tko > 8.4} { $tex configure -inactiveselectbackground $inacback } } } foreach ent $entlist { if {[winfo exists $ent]} { $ent configure -bg $entback -fg $entfore } } foreach head $headlist { if {[winfo exists $head]} { $head configure -bg $headback -fg $headfore } } foreach light $lightlist { if {[winfo exists $light]} { $light configure -bg $lightback -fg $lightfore } } foreach spin $spinlist { if {[winfo exists $spin]} { $spin configure -buttonbackground $buttback } } foreach butt [list .colo.winback .colo.winfore .colo.selback \ .colo.selfore .colo.buttback .colo.buttfore .colo.miniback \ .colo.minifore .colo.listback .colo.listfore .colo.textback \ .colo.textfore .colo.inacback .colo.linktex .colo.entback \ .colo.entfore .colo.headback .colo.headfore .colo.lightback \ .colo.lightfore] { colorgrip $butt } colorcheck } # Procedure to save color configuration: proc savecolo {colofile} { set colosaver "set ::winback \"$::winback\"\ \nset ::winfore \"$::winfore\"\ \nset ::selback \"$::selback\"\ \nset ::selfore \"$::selfore\"\ \nset ::buttback \"$::buttback\"\ \nset ::buttfore \"$::buttfore\"\ \nset ::miniback \"$::miniback\"\ \nset ::minifore \"$::minifore\"\ \nset ::listback \"$::listback\"\ \nset ::listfore \"$::listfore\"\ \nset ::textback \"$::textback\"\ \nset ::textfore \"$::textfore\"\ \nset ::inacback \"$::inacback\"\ \nset ::linktex \"$::linktex\"\ \nset ::entback \"$::entback\"\ \nset ::entfore \"$::entfore\"\ \nset ::headback \"$::headback\"\ \nset ::headfore \"$::headfore\"\ \nset ::lightback \"$::lightback\"\ \nset ::lightfore \"$::lightfore\"\ \nset ::newsel \"$::newsel\"\ \nset ::oldsel \"$::oldsel\"" set filid [open $colofile w] puts -nonewline $filid $colosaver close $filid } ### Color-scheme procedures # Procedure to show color-scheme name in entry widget: proc showschemename {} { .colo.schement delete 0 end after 10 { set getline [.colo.schemelist curselection] .colo.schement insert 0 [.colo.schemelist get $getline] .colo.schement selection range 0 end } } # Procedure to name color scheme: proc name_scheme {} { global schemelist # Apply picked colors, if they haven't been applied: .colo.schemelist selection clear 0 end showcolo set isaname [.colo.schement get] # Don't accept a color scheme with no name: if {$isaname eq ""} { tk_messageBox -message "Please enter a name for this color scheme" \ type ok return } # Ask whether to change an existing color scheme: set thisname [lsearch $schemelist $isaname] if {$thisname != -1} { set revise [tk_messageBox -message "Revise\n\"$isaname\"\n\ color scheme?" -type yesno] if {$revise eq "yes"} { # Avoid duplication of name: .colo.schemelist delete $thisname } } # Get rid of any non-space characters that don't belong in file names: set isaname [regsub -all \\W $isaname {}] # Show the name in the list of color schemes: lappend schemelist $isaname set schemelist [lsort -dictionary $schemelist] .colo.schemelist selection set [lsearch $schemelist $isaname] # Blank out the entry line: .colo.schement delete 0 end # Now make a real file name: set isafile [file join $::schemedir [string map "{ } _" $isaname].tcl] # Save the current color scheme in the file: set colorsaver "set ::winback \"$::winback\"\ \nset ::winfore \"$::winfore\"\ \nset ::selback \"$::selback\"\ \nset ::selfore \"$::selfore\"\ \nset ::buttback \"$::buttback\"\ \nset ::buttfore \"$::buttfore\"\ \nset ::miniback \"$::miniback\"\ \nset ::minifore \"$::minifore\"\ \nset ::listback \"$::listback\"\ \nset ::listfore \"$::listfore\"\ \nset ::textback \"$::textback\"\ \nset ::textfore \"$::textfore\"\ \nset ::inacback \"$::inacback\"\ \nset ::linktex \"$::linktex\"\ \nset ::entback \"$::entback\"\ \nset ::entfore \"$::entfore\"\ \nset ::headback \"$::headback\"\ \nset ::headfore \"$::headfore\"\ \nset ::lightback \"$::lightback\"\ \nset ::lightfore \"$::lightfore\"\ \nset ::newsel \"$::newsel\"\ \nset ::oldsel \"$::oldsel\"" set filid [open $isafile w] if {[catch {puts -nonewline $filid $colorsaver} nosave]} { tk_messageBox -message $nosave -type ok } close $filid } # Procedure to retrieve color-scheme names: proc getschemes {} { global schemelist set schemelist [list] set schemeroo [lsort -dictionary [glob -nocomplain -tails \ -directory $::schemedir *]] foreach scheme $schemeroo { lappend schemelist [string map "_ { }" [file rootname $scheme]] } } # Procedure to apply color scheme: proc apply_scheme {} { set schemer [string map "{ } _" [.colo.schemelist get \ [.colo.schemelist curselection]]] set schemefile [file join $::schemedir ${schemer}.tcl] source $schemefile foreach lab [list .colo.winback .colo.winfore .colo.selback \ .colo.selfore .colo.buttback .colo.buttfore .colo.miniback \ .colo.minifore .colo.listback .colo.listfore .colo.textback \ .colo.textfore .colo.inacback .colo.linktex .colo.entback \ .colo.entfore .colo.headback .colo.headfore .colo.lightback \ .colo.lightfore] { colortext $lab colorgrip $lab } showcolo } # Procedure to delete color scheme: proc delete_scheme {} { set picker [.colo.schemelist curselection] set schemer [string map "{ } _" [.colo.schemelist get $picker]] set schemefile [file join $::schemedir ${schemer}.tcl] file delete $schemefile .colo.schemelist delete $picker } # Get color configuration file, if available: set appcolo [file join $wishdir comcolo.tcl] if {[file readable $appcolo]} { source $appcolo } # Use some of the specified color variables: tk_setPalette background $winback foreground $winfore selectBackground \ $selback selectForeground $selfore # Procedure to find out whether executable program is in system's PATH or not: proc inpath {prog} { global env set exok 0 set envlist [split $env(PATH) :] foreach direc $envlist { if {[file executable [file join $direc $prog]]} { set exok 1 break } } return $exok } # Which program to use for printing (Unix-type systems only): if {[inpath xpp]} { set printprog xpp } else { set printprog lpr } # Integer range generator for "foreach" # (to do a "for" loop without ugly, awkward "for" code): proc range {start cutoff finish {step 1}} { # If "start" and "finish" aren't integers, do nothing: if {[string is integer -strict $start] == 0 || [string is\ integer -strict $finish] == 0} { error"range:Rangemustcontaintwointegers" } # "Step" has to be an integer too, and # no infinite loops that go nowhere are allowed: if {$step == 0 || [string is integer -strict $step] == 0} { error "range: Step must be an integer other than zero" } # Does the range include the last number? switch $cutoff { "to" {set inclu 1} "no" {set inclu 0} default { error "range: Use \"to\" for an inclusive range,\ or \"no\" for a noninclusive range" } } # Is the range ascending or descending (or neither)? set ascendo [expr $finish - $start] if {$ascendo > -1} { set up 1 } else { set up 0 } # If range is descending and step is positive but doesn't have a "+" sign, # change step to negative: if {$up == 0 && $step > 0 && [string first "+" $start] != 0} { set step [expr $step * -1] } set ranger [list] ; # Initialize list variable for generated range switch "$up $inclu" { "1 1" {set op "<=" ; # Ascending, inclusive range} "1 0" {set op "<" ; # Ascending, noninclusive range} "0 1" {set op ">=" ; # Descending, inclusive range} "0 0" {set op ">" ; # Descending, noninclusive range} } # Generate a list containing the specified range of integers: for {set i $start} "\$i $op $finish" {incr i $step} { lappend ranger $i } return $ranger } ### GUI SETUP ### # Procedure to change display on title bar: proc wmtitle {} { global currentfile if {$currentfile eq ""} { if {[.tx edit modified]} { wm title . "WISH Supernotepad (Save?)" } else { wm title . "WISH Supernotepad" } } else { if {[.tx edit modified]} { wm title . "WISH Supernotepad (Save?) : $currentfile " } else { wm title . "WISH Supernotepad : $currentfile" } } bind . <Key> {after 10 saveup} bind . <Button-2> {after 10 saveup} } # Make and arrange mini-toolbar buttons: frame .froolbar button .new -text "New" -command file_new button .open -text "Open" -command {set openins Open ; openrece file} button .ins -text "Insert" -command {matchinline file} button .save -text "Save" -command file_save button .backup -text "Backup" -command backup button .print -text "Print?" -command printbox button .cut -text "Cut" -command cut_text button .copy -text "Copy" -command copy_text button .paste -text "Paste" -command paste_text button .undo -text "Undo" -command {catch {.tx edit undo}} button .redo -text "Redo" -command {catch {.tx edit redo}} button .special -text "Special" -command specialbox button .findbutt -text "Find" -command findwhat button .repbutt -text "Replace" -command search_replace button .quit -text "Quit" -command gitoot set miniline [list .new .open .ins .save .backup .print .cut .copy \ .paste .undo .redo .special .findbutt .repbutt .quit] foreach mini $miniline { $mini configure -pady 0 -padx 0 -bord 1 -bg $::miniback -fg $::minifore pack $mini -in .froolbar -side left -expand 1 -fill both } grid .froolbar -row 0 -column 0 -columnspan 2 -sticky news # Make the text area and scrollbars: grid [text .tx -width $texwid -height $texhi -bg $::textback \ -fg $::textfore -wrap $wordwrap -setgrid 1 -undo 1 \ -font "$fontaine" -tabs {36 72 108 144 180 216 252 288}] \ -row 3 -column 0 -sticky news if {$tclo > 8.4} { .tx configure -inactiveselectbackground $::inacback } grid [scrollbar .ybar -width 12 -command ".tx yview"] \ -row 3 -column 1 -sticky news grid [scrollbar .xbar -width 12 -command ".tx xview" \ -orient horizontal] \ -row 4 -column 0 -columnspan 2 -sticky news .tx configure -xscrollcommand ".xbar set" \ -yscrollcommand ".ybar set" grid rowconfigure . 3 -weight 1 grid columnconfigure . 0 -weight 1 focus .tx set foco .tx bind .tx <FocusIn> {set foco .tx} .tx edit separator .tx edit modified 0 wmtitle # Procedure to get ready to remove old contents from text area: proc readytogo {} { set exitanswer "" if {[.tx edit modified]} { if {$::currentfile ne ""} { file_save } else { set exitanswer [tk_messageBox -message "Save changes?" \ -title "Save changes?" -type yesnocancel -icon question] if {$exitanswer eq "yes"} { file_saveas } } } if {$exitanswer eq "cancel"} { return 0 } else { return 1 } } # Procedure to remove old contents from text area: proc outwithold {} { set ::currentfile "" set ::backfile "" .tx delete 1.0 end .tx edit reset .tx edit modified 0 } # Procedure to get saved changes recognized at once: proc saveup {} { if {[.tx edit modified]} { bind .tx <Key> {} bind .tx <Button-2 {} wmtitle } else { after 100 saveup } } # Procedure to put contents of new file into text area: proc inwithnew {} { global newfile currentfile platform if {$newfile eq "" || [file readable $newfile] == 0} { return } set star [open $newfile "r"] set filecont [read $star] set filecont [string trimright $filecont] .tx insert insert $filecont set currentfile $newfile .tx edit reset .tx edit modified 0 wmtitle close $star } # Procedure to clear out irrelevancies so that special widgets # (Find, Replace, various HTML ones, etc.) can do their work: proc clearout {} { foreach w $::clearframes { catch {grid remove $w} } } # List of possible irrelevancies to be cleared out: set clearframes [list .prin .need .findreg .replace .fin .fregexp \ .linenum .head .font .anchor .html_list] # Procedure to dethrone special widget: proc clearin {w_out} { catch {grid remove $w_out} focus .tx set foco .tx } ### MAIN MENU ### menu .filemenu -tearoff 0 -borderwidth 1 ### FILE MENU ### menu .filemenu.files -tearoff 0 .filemenu add cascade -label "File" -underline 0 -menu .filemenu.files ### File -- New Text .filemenu.files add command -label "New Text" \ -underline 0 -command file_new proc file_new {} { set go [readytogo] if {$go == 0} {return} outwithold .tx edit separator .tx edit modified 0 wmtitle } ### File -- New HTML .filemenu.files add command -label "New HTML" \ -underline 4 -command new_html proc new_html {} { global converto set go [readytogo] if {$go == 0} {return} outwithold .tx edit separator .tx insert 1.0 "<html>\n<head>\ \n\t<meta name=\"generator\" content=\"WISH Supernotepad\" /> \ \n\t<meta http-equiv=\"Content-Type\" content=\"text/html;\ charset=ISO-8859-1\" /> \ \n<!-- Document title (to be displayed on title bar\ \n\tof browser) goes in space below -->\ \n\t<title>\n\n\ \n\n</title>\n\t<style type=\"text/css\">\ \n\t</style>\n</head>\n\n<body\ text=\"#000000\" link=\"#0000FF\" vlink=\"#FF0000\" alink\ =\"#FF0000\" bgcolor=\"#FFFFFF\">" if {$converto == 0} { .tx insert end "\n\ \n<!-- Contents of document (to be displayed in main browser\ window) go in space below -->\n\n\n\n</body>\n</html>" } else { .tx insert end "\n\n\n\n</body>\n</html>" } .tx mark set insert 9.0 .tx edit reset .tx edit modified 0 after 1000 wmtitle } ### File -- New Window .filemenu.files add command -label "New Window" -underline 4 \ -accelerator Ctrl+n -command {eval exec supernotepad &} bind . <Control-n> {eval exec supernotepad &} .filemenu.files add separator ### File -- Open Any .filemenu.files add command -label "Open Any" \ -underline 0 -command {file_open any} proc file_open {which} { global newfile currentfile filetosave openins openew set openins Open set go [readytogo] if {$go == 0} {return} if {$which eq "any"} { set newfile [tk_getOpenFile] } if {$newfile ne ""} { if {$openew == 1} { eval exec supernotepad $newfile & } else { outwithold inwithnew .tx mark set insert 1.0 saverece } } if {[winfo exists .rece]} { destroy .rece } } ### File -- Open Recent .filemenu.files add command -label "Open Recent" -underline 5 -command { set openins Open openrece file } -accelerator "Ctrl+. (period)" bind . <Control-period> {set openins Open ; openrece file} # Procedure to make GUI box for selecting # recently opened or inserted files # (also used for selecting "Superpaste" items): proc openrece {what} { global wishdir recentlist reclim newfile addfile mandatum \ foco currentfile openins findum pastelist pastelim openew # Open file in new window if there's one in current window: if {$currentfile ne ""} { set openew 1 } set findum "" toplevel .rece grid [listbox .rece.list -width 72 -height 16 -bg $::listback \ -fg $::listfore -selectmode extended] -row 0 -column 0 -sticky news grid [scrollbar .rece.rolly -width 12 -command [list .rece.list yview]] \ -row 0 -column 1 -sticky news grid [scrollbar .rece.rollx -orient horizontal -width 12 \ -command [list .rece.list xview]] \ -row 1 -column 0 -columnspan 2 -sticky news .rece.list configure -xscrollcommand ".rece.rollx set" \ -yscrollcommand ".rece.rolly set" frame .rece.fir button .rece.find -text "Search" -relief groove -border 3 \ -command findrece entry .rece.ent -bg $::entback -fg $::entfore -width 48 \ -textvariable findum label .rece.found -relief sunken -border 2 -text "0 found" pack .rece.find .rece.ent .rece.found -in .rece.fir \ -side left -expand 1 -fill both grid .rece.fir -row 2 -column 0 -columnspan 2 -sticky news frame .rece.fr checkbutton .rece.new -text "New window?" -variable openew \ -selectcolor $::regradio if {$openins ne "Open" || $what ne "file"} { .rece.new configure -state disabled } button .rece.open # This button isn't for Superpaste: button .rece.all -text "$openins Any" -command { if {$openins == "Insert"} { file_insert any } else { file_open any } } button .rece.whole -text "See Whole" -command seewhole label .rece.show -text "Show" spinbox .rece.spin -width 4 -from 1 -to 9999 -bg $::entback \ -fg $::entfore -buttonbackground $::buttback label .rece.fils button .rece.unlist -text "Unlist" -command "unlisto $what" button .rece.close -text "Close" -command {destroy .rece} foreach butt [list .rece.find .rece.open .rece.all .rece.unlist \ .rece.whole .rece.close] { $butt configure -pady 2 -padx 4 -bg $::buttback -fg $::buttfore } grid .rece.fr -row 3 -column 0 -columnspan 2 -sticky news .rece.list see end grid columnconfigure .rece 0 -weight 1 grid rowconfigure .rece 0 -weight 1 if {$what eq "paste"} { wm title .rece "Superpaste" .rece.list configure -listvariable pastelist bind .rece <Key-Return> {findrece paste} .rece.open configure -text "Superpaste" -command superpaste .rece.spin configure -textvariable pastelim .rece.fils configure -text "items" pack .rece.new .rece.open .rece.whole .rece.show .rece.spin \ .rece.fils .rece.unlist .rece.close -in .rece.fr \ -side left -expand 1 -fill both set mandatum superpaste } else { wm title .rece "$openins Recently Viewed File" .rece.list configure -listvariable recentlist bind .rece <Key-Return> {findrece rece} .rece.open configure -text $openins -command openorins .rece.spin configure -textvariable reclim .rece.fils configure -text "files" pack .rece.new .rece.open .rece.all .rece.show .rece.spin \ .rece.fils .rece.unlist .rece.close -in .rece.fr \ -side left -expand 1 -fill both set mandatum openorins } bind .rece.list <Double-Button-1> {eval $mandatum} bind .rece.list <Button-3> { selection clear set clixel %y set clickline [.rece.list nearest $clixel] .rece.list selection set $clickline $clickline eval $mandatum } focus .rece.ent .rece.list see end } # Procedure to paste item from "Superpaste" list: proc superpaste {} { global pastelist foco set recenum [.rece.list curselection] if {[llength $recenum] != 1} { tk_messageBox -message "Please insert one selection\ at a time" -type ok } else { $foco insert insert [.rece.list get $recenum] } selection clear .rece.found configure -text "0 found" .rece.ent delete 0 end } # Procedure to see whole item on "Superpaste" list: proc seewhole {} { global foco set seenum [.rece.list curselection] if {[llength $seenum] != 1} { tk_messageBox -message "Please select exactly one\ text item to view" -type ok return } toplevel .see wm title .see "See Whole" grid [text .see.whole -bg $::textback -fg $::textfore] \ -row 0 -column 0 -sticky news grid [scrollbar .see.ybar -width 12 -command ".see.whole yview"] \ -row 0 -column 1 -sticky news grid [scrollbar .see.xbar -width 12 -orient horizontal \ -command "see.whole xview"] -row 1 -column 0 \ -columnspan 2 -sticky news .see.whole configure -xscrollcommand ".see.xbar set" \ -yscrollcommand ".see.ybar set" frame .see.fr button .see.ins -text "Insert" -command { superpaste destroy .see } button .see.close -text "Close" -command {destroy .see} pack .see.ins .see.close -in .see.fr -side left -expand 1 -fill both grid .see.fr -row 2 -column 0 -columnspan 2 -sticky news .see.whole insert insert [.rece.list get $seenum] } # Procedure to find name of recently viewed file # or item in "Superpaste" list: proc findrece {which} { global findum recentlist pastelist if {$which eq "paste"} { set listo $pastelist } else { set listo $recentlist } set whatitis [lsearch -all $listo *$findum*] set howmany [llength $whatitis] if {$howmany > 0} { .rece.found configure -text "$howmany found" foreach it $whatitis { .rece.list selection set $it } .rece.list see [lindex $whatitis 0] } else { set findum "NOT FOUND" .rece.ent selection range 0 end .rece.ent icursor end } } # Procedure to open or insert recently viewed file: proc openorins {} { global addfile newfile openins openew set recenum [.rece.list curselection] if {[llength $recenum] != 1} { tk_messageBox -message "Please select exactly one file" -type ok selection clear } else { set receline [.rece.list get $recenum] if {$openins eq "Insert"} { set addfile $receline file_insert recent } else { if {$openew == 1} { eval exec supernotepad $receline & } else { set newfile $receline file_open recent } } if {[winfo exists .rece]} { destroy .rece } } } # Procedure to delete listings of recently viewed files, # or of "Superpaste" items: proc unlisto {which} { set delrec [.rece.list curselection] set delleng [expr [llength $delrec] -1] foreach d [range $delleng to 0] { set delnum [lindex $delrec $d] .rece.list delete $delnum } if {$which eq "paste"} { savepaste } else { saverece } } # Procedure to save list of recently opened or inserted files: proc saverece {} { global recentlist wishdir newfile currentfile \ reclim openins addfile dumpfile rece set recleng [expr {[llength $recentlist] -1}] foreach r [range $recleng to 0] { set rindex [lindex $recentlist $r] if {$openins eq "Insert" && $rindex eq $addfile} { set recentlist [lreplace $recentlist $r $r] } elseif {$rindex eq $currentfile || $rindex eq $dumpfile} { set recentlist [lreplace $recentlist $r $r] } } if {$recleng > $reclim} { set limless [expr {$recleng-$reclim-1}] set recentlist [lreplace $recentlist 0 $limless] } if {$openins eq "Insert"} { lappend recentlist $addfile } else { lappend recentlist $currentfile } set recfil [open $rece "w"] set recentex "set reclim $reclim\nset recentlist \[list $recentlist\]" puts -nonewline $recfil $recentex close $recfil } ### File -- Open (New Window) .filemenu.files add command -label "Open (New Window)" \ -underline 13 -command openwin # Procedure to open file in new window: proc openwin {} { set newfie [tk_getOpenFile] if {$newfie ne ""} { eval exec supernotepad $newfie & } } .filemenu.files add separator ### File -- Save .filemenu.files add command -label "Save" -underline 0 \ -command "file_save" -accelerator Ctrl+s bind . <Control-s> {file_save} proc file_save {} { global currentfile filecont set filecont [.tx get 1.0 end] set texttosave [string trimright $filecont] if {$currentfile ne ""} { set fileid [open $currentfile "w"] puts $fileid $filecont close $fileid .tx edit reset .tx edit modified 0 wm title . "WISH Supernotepad : Saved $currentfile" after 1000 wmtitle } else {file_saveas} } ### File -- Save As .filemenu.files add command -label "Save As" -underline 5 \ -command "file_saveas" proc file_saveas {} { global currentfile newfile filecont filetosave if {[file writable $currentfile]} { file_save } else { set filecont [.tx get 1.0 end] } set texttosave [string trimright $filecont] if {$currentfile ne ""} { set initdir [file dirname $currentfile] } else { set initdir [pwd] } set filetosave [tk_getSaveFile -initialdir $initdir] if {$filetosave eq ""} { return } set fileid [open $filetosave "w"] puts $fileid $filecont close $fileid set currentfile $filetosave .tx edit reset .tx edit modified 0 saverece wm title . "WISH Supernotepad : Saved $currentfile" after 1000 wmtitle } ### File -- Backup .filemenu.files add command -label "Backup" -command backup proc backup {} { global currentfile backfile if {$currentfile ne ""} { if {[.tx edit modified]} { file_save } } else { tk_messageBox -message "Contents must be saved under one name\ before they can be backed up under another name" -type ok return } if {[file writable $backfile]} { file copy -force $currentfile $backfile wm title . "WISH Supernotepad : File backed up as $backfile" after 1000 wmtitle } else { backup_as } } ### File -- Backup As .filemenu.files add command -label "Backup As" -underline 0 \ -command "backup_as" proc backup_as {} { global currentfile backfile if {$currentfile ne ""} { if {[.tx edit modified]} { file_save } } else { tk_messageBox -message "Contents must be saved under one name\ before they can be backed up under another name" -type ok return } set initdir [file dirname $currentfile] set backfile [tk_getSaveFile -title "Backup As" -initialdir $initdir] if {$backfile ne ""} { file copy -force $currentfile $backfile wm title . "WISH Supernotepad : File backed up as $backfile" after 1000 wmtitle } } ### File -- Move/Rename .filemenu.files add command -label "Move/Rename" -underline 0 \ -command "file_rename" # Procedure to move or rename file: proc file_rename {} { global currentfile dumpfile if {$currentfile ne ""} { set initdir [file dirname $currentfile] } else { set initdir [pwd] } set newname [tk_getSaveFile -title "Move/Rename File" -initialdir $initdir] if {$newname ne ""} { set dumpfile $currentfile file rename -force $currentfile $newname set currentfile $newname file_save saverece } } .filemenu.files add separator ### File -- Import Palm Doc .filemenu.files add command -label "Import Palm Doc" -command openpalm proc openpalm {} { global palmdir env newfile platform # WISH Supernotepad uses "txt2pdbdoc" to convert # to and from Palm Doc format: foreach prog [list txt2pdbdoc html2pdbtxt] { if {[inpath $prog] == 0} { tk_messageBox -message "WISH Supernotepad requires the free\ \"txt2pdbdoc\" and \"html2pdbtxt\" programs for conversion\ to and from Palm Doc format" -type ok return } elseif {$platform ne "unix"} { tk_messageBox -message "Sorry, WISH Supernotepad's Palm Doc\ conversion feature will work only on Unix-type systems"\ -type ok return } } if {$palmdir eq ""} { set initdir $env(HOME) } else { set initdir $palmdir } set palmtype { {"Palm Doc" {".pdb"}} } set texttype { {"Plain Text" {".txt"}} } set newpalm [tk_getOpenFile -filetypes $palmtype -initialdir $initdir \ -title "Open Palm Doc"] if {$newpalm ne ""} { set palmdir [file dirname $newpalm] set destiname [tk_getSaveFile -title "Name & Directory of\ Text File" -filetypes $texttype] if {$destiname eq ""} { tk_messageBox -message "Content from Palm Doc must be given\ name and directory as text file" -type ok return } grid [label .palm -text "Converting from Palm Doc format ..." \ -font "helvetica 18 bold"] -row 1 -column 0 -columnspan 2 \ -sticky news exec txt2pdbdoc -d "$newpalm" "$destiname" set newfile $destiname file_open palm } destroy .palm } ### File -- Export As Palm Doc .filemenu.files add command -label "Export As Palm Doc" -command exportpalm proc exportpalm {} { global currentfile wishdir platform palmdir env # WISH Supernotepad uses "txt2pdbdoc" to convert # to and from Palm Doc format: foreach prog [list txt2pdbdoc html2pdbtxt] { if {[inpath $prog] == 0} { tk_messageBox -message "WISH Supernotepad requires the free\ \"txt2pdbdoc\" and \"html2pdbtxt\" programs for conversion\ to and from Palm Doc format" -type ok return } elseif {$platform ne "unix"} { tk_messageBox -message "Sorry, WISH Supernotepad's Palm Doc\ conversion feature will work only on Unix-type systems"\ -type ok return } } if {$palmdir eq ""} { set initdir $env(HOME) } else { set initdir $palmdir } set palmcont [string trim [.tx get 1.0 end]] set tempee [file join $env(HOME) wishes tempee] set tempnum [open $tempee w] puts -nonewline $tempnum $palmcont close $tempnum set filtip [exec file $tempee] if {[regexp HTML $filtip]} { set textcont [exec html2pdbtxt "$tempee"] set filid [open "$tempee" w] puts -nonewline $filid $textcont close $filid } set texttype { {"Palm Doc" {".pdb"}} } set palmtitle [tk_getSaveFile -title "Descriptive Title for Palm Doc" \ -initialdir $initdir -filetypes $texttype -defaultextension .pdb] if {$palmtitle ne ""} { set palmroot [file tail [file rootname $palmtitle]] exec txt2pdbdoc "$palmroot" "$tempee" "$palmtitle" } file delete $tempee wm title . "WISH Supernotepad : Exported $palmtitle" after 1000 wmtitle } .filemenu.files add separator ### File -- Print .filemenu.files add command -label "Print?" -underline 0 \ -command printbox -accelerator Ctrl+q bind . <Control-q> printbox # Procedure to set up dialog bar for printing: proc printbox {} { global texwid formawid fonto printprog platform if {$platform ne "unix"} { tk_messageBox -message "Sorry, only Unix-type systems can print\ directly from WISH Supernotepad." -type ok return } clearout set formawid $texwid if {[winfo exists .prin]} { grid .prin } else { frame .prin label .prin.tex -text "Text width:" -pady 0 spinbox .prin.spin -width 3 -from 20 -to 200 -textvariable formawid label .prin.lab -text "Set other options when X Printing\ Panel (XPP) is running" button .prin.ok -takefocus 0 -command { filetoprint clearin .prin } button .prin.close -text "Close" -pady 0 -border 1 \ -takefocus 0 -command { clearin .prin } pack .prin.tex .prin.spin .prin.lab .prin.ok .prin.close \ -in .prin -side left -expand 1 -fill both grid .prin -row 1 -column 0 -columnspan 2 -sticky news focus .prin.spin } .prin.spin configure -bg $::entback -fg $::entfore \ -buttonbackground $::buttback foreach butt [list .prin.ok .prin.close] { $butt configure -bg $::buttback -fg $::buttfore } printswitch focus .prin.spin } # Procedure to use X Printing Panel (XPP) for printing # if available, otherwise lpr: proc printswitch {} { global printprog if {$printprog eq "xpp"} { .prin.lab configure -state normal .prin.ok configure -text "Print with XPP" } else { .prin.lab configure -state disabled .prin.ok configure -text "Print with LPR" } } # Procedure to save file (if necessary) and format it for printing; proc filetoprint {} { global platform currentfile fonto wishdir printprog \ formawid texwid wordwrap set go [readytogo] if {$go == 0} {return} .tx configure -width $formawid -wrap word wm geometry . {} if {$currentfile ne ""} { set ::curprint [file rootname $currentfile] } else { set ::curprint [file join $wishdir printtemp] } append ::curprint ".fmt" after 1000 { set formex [formatit print] set fileid [open $::curprint "w"] puts -nonewline $fileid $formex close $fileid .tx configure -width $texwid -wrap $wordwrap wm geometry . {} eval exec $printprog $::curprint & } } .filemenu.files add separator ### File -- Exit .filemenu.files add command -label "Exit" -underline 1 -command gitoot # Procedure to shut down properly: proc gitoot {} { global curprint if {[.tx edit modified]} { set seeya 1 } else { set seeya 0 } set go [readytogo] if {$go == 0} {return} savefig if {[file exists $curprint]} { file delete $curprint } if {$seeya == 0 || [regexp {Saved} [wm title .]] == 0} { exit } else { # Give the user half a second to see that changes have been saved: after 500 exit } } # Procedure to save configuration: proc savefig {} { set figlines "set openins $::openins\ \nset texwid $::texwid\ \nset formawid $::formawid\ \nset texhi $::texhi\ \nset wordwrap $::wordwrap\ \nset fonto \"$::fonto\"\ \nset siz $::siz\ \nset fontaine \"$::fontaine\"\ \nset printprog $::printprog\ \nset reunito $::reunito\ \nset parsep $::parsep\ \nset expert $::expert\ \nset headsize $::headsize\ \nset html_fontsize $::html_fontsize\ \nset listtype $::listtype\ \nset autotab $::autotab" set filid [open $::superfig w] puts -nonewline $filid $figlines close $filid } ### EDIT MENU ### # using built-in procedures tk_textCut, tk_textCopy, tk_textPaste menu .filemenu.edit -tearoff 0 .filemenu add cascade -label "Edit" -underline 0 -menu .filemenu.edit ### Edit -- Cut .filemenu.edit add command -label "Cut" -underline 2 \ -command cut_text -accelerator Ctrl+x bind . <Control-x> {cut_text ; break} proc cut_text {} { global foco if {[winfo class $foco] eq "Text"} { tk_textCut $foco $foco edit separator if {$foco eq ".tx"} { wmtitle } } } ### Edit -- Copy .filemenu.edit add command -label "Copy" -underline 0 \ -command copy_text -accelerator Ctrl+c bind . <Control-c> {copy_text ; break} proc copy_text {} { global foco if {[winfo class $foco] eq "Text"} { tk_textCopy $foco } } ### Edit -- Paste .filemenu.edit add command -label "Paste" -underline 0 \ -command paste_text -accelerator Ctrl+g bind . <Control-g> paste_text # <Control-v> didn't work quite right--I don't know why. proc paste_text {} { global foco if {[winfo class $foco] eq "Text"} { tk_textPaste $foco $foco edit separator if {$foco eq ".tx"} { wmtitle } } } ### Edit -- Delete .filemenu.edit add command -label "Delete" -underline 0 \ -command delete_text -accelerator Del proc delete_text {} { .tx delete sel.first sel.last .tx edit separator wmtitle } .filemenu.edit add separator ### Edit -- Supercut .filemenu.edit add command -label "Supercut" \ -command supercut -accelerator Ctrl+X bind . <Control-X> supercut proc supercut {} { global foco pastelist if {[winfo class $foco] eq "Text"} { set anysel [catch {$foco get sel.first sel.last} pastee] if {$anysel == 0} { if {[lsearch $pastelist $pastee] == -1} { lappend pastelist $pastee } savepaste } tk_textCut $foco $foco edit separator if {$foco eq ".tx"} { wmtitle } } } ### Edit -- Supercopy .filemenu.edit add command -label "Supercopy" \ -command supercopy -accelerator Ctrl+C bind . <Control-C> supercopy proc supercopy {} { global foco pastelist if {[winfo class $foco] eq "Text"} { set anysel [catch {$foco get sel.first sel.last} pastee] if {$anysel == 0} { if {[lsearch $pastelist $pastee] == -1} { lappend pastelist $pastee } savepaste } tk_textCopy $foco } else { if {[selection own] eq $foco} { lappend pastelist [selection get] savepaste } } } ### Edit -- Superpaste .filemenu.edit add command -label "Superpaste" -underline 3 \ -command {matchinline paste} -accelerator F1 bind . <F1> {matchinline paste} # Procedures to view, select, and paste text from "Superpaste" list # are under the "File--Open" menu item above, because they use the # same listbox with slightly different names for buttons and things # Procedure to paste text from "Superpaste" list # or to insert file from "Recent File" list, without # opening the box, if possible; if not, then to open the box: proc matchinline {whatfor} { global pastelist recentlist foco addfile openins set anysel [catch {$foco get sel.first sel.last} texas] if {$anysel == 0} { set firstum [$foco index sel.first] set lastum [$foco index sel.last] } else { set realine [realword] set texas [lindex $realine 0] set firstum [lindex $realine 1] set lastum [lindex $realine end] } set selgo [$foco index $firstum] $foco delete $firstum $lastum if {$whatfor eq "paste"} { set whatitis [lsearch -all $pastelist *$texas*] } else { set whatitis [lsearch -all $recentlist *$texas*] } set howmany [llength $whatitis] if {$howmany == 1} { set it [lindex $whatitis 0] if {$whatfor eq "paste"} { $foco insert $selgo [lindex $pastelist $it] } else { set addfile [lindex $recentlist $it] file_insert recent } } else { set openins Insert openrece $whatfor } } # Procedure to identify the real beginning of a real word # in a text widget (unlike "string wordstart"): proc realword {} { global foco set linum [line_number] set insum [$foco index insert] set linget [string trim [$foco get $linum.0 $insum]] set spa [string last " " $linget] set ta [string last "\t" $linget] if {$spa == -1 && $ta == -1} { set wordo $linget set wordleng [string length $wordo] set firsto [$foco index "$insum - $wordleng char"] } else { set spend [expr {$spa+1}] set tabend [expr {$ta+1}] if {$spend > $tabend} { set wordo [$foco get $linum.$spend $insum] set firsto $linum.$spend } else { set wordo [$foco get $linum.$tabend $insum] set firsto $linum.$tabend } } return [list $wordo $firsto $insum] } # Procedure to save "superpaste" list: proc savepaste {} { global pastelist pastelim superpaste set pastleng [expr {[llength $pastelist] -1}] if {$pastleng > $pastelim} { set limless [expr {$pastleng-$pastelim-1}] set pastelist [lreplace $pastelist 0 $limless] } set pastfil [open $superpaste "w"] set pastex "set pastelim $pastelim\nset pastelist \[list $pastelist\]" puts -nonewline $pastfil $pastex close $pastfil } .filemenu.edit add separator ### Edit -- Undo .filemenu.edit add command -label "Undo" -underline 0 -command { catch {.tx edit undo} } -accelerator Ctrl+z # Binding Ctrl+z is built in ### Edit -- Redo .filemenu.edit add command -label "Redo" -underline 0 \ -command {catch {.tx edit redo}} -accelerator Ctrl+r bind . <Control-r> {catch {.tx edit redo}} bind . <space> {.tx edit separator} bind . <BackSpace> {.tx edit separator} ### Edit -- Undo All Since Last Save .filemenu.edit add command -label "Undo All Since Last Save" \ -underline 9 -command undolast # Procedure to undo all changes since last save: proc undolast {} { global currentfile newfile if {[.tx edit modified]} { .tx delete 1.0 end if {$currentfile ne ""} { set newfile $currentfile inwithnew } else { .tx edit reset .tx edit modified 0 wmtitle } } else { tk_messageBox -message "No changes have been made since\ the last save" -type ok } } .filemenu.edit add separator ### Edit -- Title .filemenu.edit add command -label "Title" -command title proc title {} { if {[.tx tag ranges sel] eq ""} {return} set input [.tx get sel.first sel.last] set output "" set nocaps [list a an and at but by for from in into of on or the to with] set count 0 foreach word [split $input] { # Strip quotation marks: if {[string index $word 0] == "\""} { set quote 1 set word [string trim $word \"] } else { set quote 0 } # Always capitalize the first word; otherwise, # don't capitalize any words in the "nocaps" list: if {$count == 0 || [lsearch $nocaps $word] == -1} { set word [string totitle $word] } # Add word plus space, with or without quotation marks, to output: if {$quote} { append output "\"$word\" " } else { append output "$word " } # Capitalize any word after a colon: if {[string index $word end] == ":"} { set count 0 } else { incr count } } set inhere [.tx index sel.first] .tx delete sel.first sel.last .tx insert $inhere [string trim $output] } .filemenu.edit add command -label "Untitle" -command untitle ### Edit -- Untitle proc untitle {} { if {[.tx tag ranges sel] eq ""} {return} set input [.tx get sel.first sel.last] set inhere [.tx index sel.first] .tx delete sel.first sel.last .tx insert $inhere [string tolower $input] } .filemenu.edit add separator ### Edit -- Select All .filemenu.edit add command -label "Select all" -underline 7 \ -command ".tx tag add sel 1.0 end" -accelerator Ctrl+/ # binding <Control-/> is built-in ### Edit -- Auto-tab .filemenu.edit add checkbutton -variable autotab -label "Auto-tab"\ -underline 5 -selectcolor $winfore -command autotaborno proc autotaborno {} { global autotab if {$autotab == 1} { bind . <Key-Return> {autotab go ; .tx edit separator} bind . <Shift-Return> {autotab stop} } else { bind . <Key-Return> {.tx edit separator} bind . <Shift-Return> {} } } autotaborno # Procedure to find out how many tabs at beginning of line: proc tabgrab {} { global charno tabno bogno if {[.tx get $bogno.$charno] eq "\t"} { incr tabno incr charno tabgrab } } # Procedure to auto-tab: proc autotab {stoporgo} { global tabno charno bogno set bogno [expr [line_number] -1] set charno 0 set tabno 0 tabgrab set herenow [.tx index insert] set gripchar [.tx get "$herenow -2c" $herenow] set gripchar [string trim $gripchar] if {$gripchar eq "\{"} { incr tabno } if {$stoporgo eq "stop"} { if {$tabno > 0} { incr tabno -1 } } set tabstring [string repeat "\t" $tabno] .tx insert insert $tabstring .tx edit separator if {$stoporgo eq "stop"} { .tx mark set insert "insert +1c" } } ### INSERT MENU ### menu .filemenu.insert -tearoff 0 .filemenu add cascade -label "Insert" -underline 0 -menu .filemenu.insert ### Insert -- File -- Any .filemenu.insert add command -label "File--Any" -underline 0 \ -command "file_insert any" proc file_insert {which} { global addfile openins foco set openins Insert # Variable "addfile" may already have been set # by another procedure. If not, do this: if {$which eq "any"} { set addfile [tk_getOpenFile -title "Insert File"] } if {$addfile ne ""} { set star [open $addfile "r"] set filecont [read $star] close $star set filecont [string trimright $filecont] $foco insert insert $filecont $foco edit separator $foco see insert wmtitle } else { unset addfile } if {[winfo exists .rece]} { destroy .rece } } .filemenu.insert add command -label "File--Recent" -underline 6 \ -command {matchinline file} -accelerator "Ctrl+, (comma)" bind . <Control-comma> {matchinline file} .filemenu.insert add separator ### Insert -- Special Characters .filemenu.insert add command -label "Special Characters" \ -underline 0 -command specialbox -accelerator F4 bind . <F4> specialbox set charlist [list \ "b "¢ "â "G "T \ "? "? "? "? "? \ "? "? "? "? "? \ "? "? "? "? "? \ "? "? "? "? "? \ "? "? "? "? "? \ "? "" "b "¢ "â \ "G "T "? "? "? \ "? "? "? "? "? \ "? "? "? "? "? \ "? "? "? "? "? \ "? "? "? "? "? \ "? "? "? "?"?\ "?"?"?"?"?\ "?"?"?"?"?\ "?"?"?"?"?? "?????????? "?????????? "???????? # Procedure for finding correct text or entry widget # and inserting special (or non-special) characters: proc findwin {char} { global foco set winclass [winfo class $foco] $foco insert insert $char if {$winclass == "Text"} { $foco edit separator wmtitle } after 10 {focus $foco} } # Procedure for setting up special-character selection box: set specialbutts [list] proc specialbox {} { global charlist foco buttlist minilist toplevel .spec wm title .spec "Special" set bigfons -adobe-helvetica-bold-r-normal--14-*-*-*-*-*-* set row 0 set col 0 foreach c [range 0 no [llength $charlist]] { set chartext [lindex $charlist $c] grid [button .spec.but($c) -text $chartext -font $bigfons \ -pady 1 -padx 2 -borderwidth 1] \ -row $row -column $col -sticky news .spec.but($c) configure -bg $::buttback -fg $::buttfore if {[lsearch $buttlist ".spec.but($c)"] < 0} { lappend buttlist .spec.but($c) } bind .spec.but($c) <Button-1> { set butt %W set charx [$butt cget -text] findwin $charx } incr col if {$col > 4} { set col 0 incr row } } grid [button .spec.amp -text "&"] -row $row -column 4 -sticky news bind .spec.amp <Button-1> {findwin "&"} set bigoe_data " #define bigoe_width 17 #define bigoe_height 13 static unsigned char bigoe_bits[] = { 0xf8, 0xfe, 0x01, 0xfe, 0xff, 0x01, 0xcf, 0x07, \ 0x00, 0x87, 0x07, 0x00, 0x07, 0x07, 0x00, 0x07, \ 0x3f, 0x00, 0x07, 0x3f, 0x00, 0x07, 0x07, 0x00, \ 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x8e, 0x07, \ 0x00, 0xfc, 0xff, 0x01, 0xf8, 0xfe, 0x01 };" image create bitmap bigoe -data $bigoe_data grid [button .spec.oebig -image bigoe \ -pady 1 -padx 2 -borderwidth 1] \ -row [expr $row+1] -column 0 -sticky news bind .spec.oebig <Button-1> {findwin "Œ"} set liloe_data " #define liloe_width 13 #define liloe_height 9 static unsigned char liloe_bits[] = { 0xbc, 0x07, 0xfe, 0x0f, 0xc3, 0x18, 0xc3, 0x18, \ 0xc3, 0x1f, 0xc3, 0x00, 0xe7, 0x18, 0xfe, 0x0f, \ 0x3c, 0x07 };" image create bitmap liloe -data $liloe_data grid [button .spec.oelil -image liloe -pady 1 \ -pady 1 -padx 2 -borderwidth 1] \ -row [expr $row+1] -column 1 -sticky news bind .spec.oelil <Button-1> {findwin "œ"} grid [button .spec.lt -text "<"] \ -row [expr $row+1] -column 2 -sticky news bind .spec.lt <Button-1> {findwin "<"} grid [button .spec.gt -text ">"] \ -row [expr $row+1] -column 3 -sticky news bind .spec.gt <Button-1> {findwin ">"} grid [button .spec.quot -text "\""] \ -row [expr $row+1] -column 4 -sticky news bind .spec.quot <Button-1> {findwin """} grid [button .spec.nbsp -text " "] \ -row [expr $row+2] -column 0 -columnspan 2 -sticky news bind .spec.nbsp <Button-1> {findwin " "} grid [button .spec.close -text "Close" \ -command {destroy .spec}] -row [expr $row+2] \ -column 2 -columnspan 3 -sticky news foreach butt [list .spec.oebig .spec.oelil .spec.nbsp .spec.amp \ .spec.lt .spec.gt .spec.quot .spec.close] { $butt configure -pady 1 -padx 2 -borderwidth 1 \ -bg $::miniback -fg $::minifore -font $bigfons if {[lsearch $minilist $butt] < 0} { lappend minilist $butt } } } .filemenu.insert add separator ### Insert -- Color Code # Get WISH Color Picker to do this job: bind . <Control-F4> { wishcolor .col.color configure -command { $foco insert insert "\"$colo\"" } } .filemenu.insert add command -label "Color Code" -underline 0 -command { wishcolor .col.color configure -command { $foco insert insert "\"$colo\"" } } -accelerator Ctrl+F4 .filemenu.insert add separator ### Insert -- Time/Date .filemenu.insert add command -label "Time/Date" \ -underline 0 -command printtime proc printtime {} { set nowtime [clock seconds] set clocktime [clock format $nowtime -format "%R %p %D"] .tx insert insert $clocktime .tx edit separator wmtitle } ### SEARCH MENU ### menu .filemenu.search -tearoff 0 .filemenu add cascade -label "Search" -underline 0 -menu .filemenu.search ### Search -- Find .filemenu.search add command -label "Find" -underline 0 \ -command findwhat -accelerator F2 bind . <F2> findwhat proc findwhat {} { if {[catch {grid info .findreg} whatnot] == 0 && $whatnot != ""} { find_text find } else { search_find } } # Initialize some variables: set casematch nocase set searchway forward set search_for "" # This shows up when search is done (see proc "find_text," below): frame .fin label .fin.is -font "helvetica 18 bold" -relief raised -border 2 button .fin.clo -pady 2 -border 2 -bg $::buttback -fg $::buttfore \ -text "Close" -command whichnew pack .fin.is .fin.clo -in .fin -side left -expand 1 -fill both # Procedure to determine whether to start over in "Find" or "Replace": proc whichnew {} { set gridslaves [grid slaves .] if {[regexp {.findreg} $gridslaves]} { newfind find } elseif {[regexp {.replace} $gridslaves]} { newfind replace } clearin .fin } # Procedure to insert starting and ending codes for HTML # (or Tcl/Tk) code and to put cursor in the right place: proc dualcodes {star cont fin} { global foco set winclass [winfo class $foco] set selon [catch {$foco index sel.first}] if {$selon == 1} { # No selected text: if {$cont == {}} { $foco insert insert "$star$fin" set goback [string length $fin] if {$winclass == "Text"} { $foco mark set insert "[$foco index insert] \ - $goback chars" $foco see insert $foco edit separator if {$foco == ".tx"} { wmtitle } } else { $foco icursor [expr [$foco index insert] - $goback] } } else { $foco insert insert "$star$cont$fin" } } else { # Text selected: $foco insert sel.first $star $foco insert sel.last "$fin" set goforth [expr {[string length $fin] +1}] if {$winclass == "Text"} { $foco mark set insert "sel.last + $goforth chars" $foco see insert $foco edit separator if {$foco eq ".tx"} { wmtitle } } else { $foco icursor [expr {[$foco index insert] + $goforth}] } } selection clear after 10 {focus $foco} } # Procedure to set up "Find" dialog bar: proc search_find {} { global search_for casematch searchway foco anytries regexy expert findex set findex .findreg clearout if {[winfo exists .findreg]} { grid .findreg } else { frame .findreg frame .find button .find.next -text "Find (F2)" -command {find_text find} entry .find.enter -width 90 -bg white -textvariable search_for pack .find.next .find.enter -in .find -side left -expand 1 -fill both frame .findex checkbutton .findex.exp -text "Expert search (with regular\ expressions)" -variable expert checkbutton .findex.match -text "Match case" \ -variable casematch -onvalue "exact" -offvalue "nocase" radiobutton .findex.up -text "Search Up" -variable searchway \ -value "backward" radiobutton .findex.down -text "Search Down" -variable searchway \ -value "forward" button .findex.new -text "New Search" -command {newfind find} button .findex.close -text "Close" -command { newfind find clearin .fin clearin .findreg } pack .findex.exp .findex.match .findex.up .findex.down .findex.new \ .findex.close -in .findex -side left -expand 1 -fill both foreach butt [list .find.next .findex.match .findex.up \ .findex.down .findex.close] { $butt configure -pady 2 } bind .find <Button-1> {set foco .find.enter} bind .find <F2> {find_text find} bind .find <F3> {findwin {<br />}} foreach {key star fin} { <F6> <p> </p> \ <F8> <i> </i> \ <F9> <b> </b> \ <Control-F6> <center> </center> } { bind .find.enter $key "dualcodes $star {} $fin" } pack .find .findex -in .findreg -side top -expand 1 -fill both grid .findreg -row 1 -column 0 -columnspan 2 -sticky news } foreach butt [list .find.next .findex.new .findex.close] { $butt configure -bg $::buttback -fg $::buttfore } foreach butt [list .findex.exp .findex.match .findex.up .findex.down] { $butt configure -selectcolor $::regradio } focus .find.enter set foco .find.enter if {$search_for ne ""} { set searchlength [string length $search_for] .find.enter selection range 0 $searchlength } set anytries 0 } # Set search direction and case sensitivity, and search for match # (Variables "present_place" and "findlength" # are set in "proc find_text," below) proc whichway {} { global casematch searchway search_reg present_place countum place switch "$casematch $searchway" { "nocase forward" { set place [.tx search -nocase -forward -regexp \ -count countum $search_reg $present_place end] } "exact forward" { set place [.tx search -forward -regexp \ -count countum $search_reg $present_place end] } "nocase backward" { set place [.tx search -nocase -backward -regexp \ -count countum $search_reg $present_place 1.0] } "exact backward" { set place [.tx search -backward -regexp \ -count countum $search_reg $present_place 1.0] } } } # Actually find some matching text proc find_text {whatfor} { global starting_place present_place search_for search_reg countum \ casematch searchway findway anytries replacelength bojo place \ replace_with expert if {$anytries == 0} { set anytries 1 set starting_place [.tx index insert] set present_place $starting_place set place $starting_place if {$whatfor eq "replace"} { set replacelength [string length $replace_with] .place.yesdo configure -text "Replace This" -command replace_one focus .with.leave bind .rep.enter <Key-Return> replace_one bind .with.leave <Key-Return> replace_one .place.nodont configure -state normal set bojo ".with.leave" } else { set bojo ".find.enter" } } set search_reg [regup $search_for] whichway if {$place eq ""} { if {$present_place eq $starting_place} { set endmess "No matching text found" } else { if {$searchway eq "forward"} { set finis "end" } else { set finis "beginning" } set endmess "Search completed from line\ [expr int($starting_place)] to $finis" } .fin.is configure -text $endmess grid .fin -row 2 -column 0 -columnspan 2 -sticky news } else { catch {.tx tag remove sel sel.first sel.last} .tx tag add sel $place "$place + $countum chars" .tx see $place if {$searchway eq "forward"} { .tx mark set insert "$place + $countum chars" } else { .tx mark set insert $place } set present_place [.tx index insert] } if {$whatfor eq "find"} { focus .tx set foco .tx } } # Procedure to start searching from scratch: proc newfind {why} { set ::search_for "" set ::anytries 0 clearin .fin if {$why eq "find"} { focus .find.enter } else { clearin .fin set ::replace_with "" set ::replacelength 0 .place.yesdo configure -text "Find First" -command {find_text replace} .place.nodont configure -state disabled set ::starting_place [.tx index insert] bind .rep.enter <Key-Return> {find_text replace} bind .with.leave <Key-Return> {find_text replace} focus .rep.enter } } # Procedure to prepare search string for use: proc regup {textin} { global expert if {$expert == 1} { set textout [string map "{ } {\\s}" $textin] } else { set textout [string map {"\{" "\\\{" "\}"\ "\\\}" "\\" "\\\\"} $textin] set textout [string map "{ } {\\s} {.} {\\.} {+} {\\+}\ {*} {\\*} {?} {\\?} {|} {\\|} {(} {\\(} {)} {\\)} {^} {\\^}\ {\$} {\\\$} {\[} {\\\[} {\]} {\\\]}" $textout] } return $textout } .filemenu.search add separator ### Search -- Replace (Standard) .filemenu.search add command -label "Replace (Standard)" -underline 0 \ -command "search_replace" -accelerator Ctrl+F2 bind . <Control-F2> search_replace # Procedures for replacing text # Set up "Replace" dialog bar: proc search_replace {} { global casematch searchway starting_place foco anytries \ search_for replace_with regexy expert findex autotab oldautotab if {$autotab == 1} { set oldautotab 1 set autotab 0 autotaborno } else { set oldautotab 0 } set findex .replace set searchway forward set starting_place [.tx index insert] clearout if {[winfo exists .replace]} { grid .replace } else { frame .replace frame .rep label .rep.what -text "Replace:" entry .rep.enter -width 90 -bg white -textvariable search_for pack .rep.what .rep.enter -in .rep -side left -expand 1 -fill both frame .with label .with.what -text "With: " entry .with.leave -width 90 -bg white -textvariable replace_with pack .with.what .with.leave -in .with -side left -expand 1 -fill both frame .place button .place.yesdo -text "Find First" -relief groove -border 3 \ -command {find_text replace} button .place.nodont -text "Skip" \ -command {find_text replace} -state disabled button .place.all -text "Replace All" \ -command replace_all checkbutton .place.exp -text "Expert search" -variable expert radiobutton .place.up -text "Up" -variable searchway \ -value "backward" radiobutton .place.down -text "Down" -variable searchway \ -value "forward" checkbutton .place.match -text "Match case" \ -variable casematch -onvalue "exact" -offvalue "nocase" button .place.new -text "New Search" -command {newfind replace} button .place.close -text "Close" -command repdoon foreach w [list .rep.what .with.what .place.yesdo .place.nodont \ .place.all .place.up .place.down .place.match .place.close] { $w configure -padx 4 } foreach butt [list .place.nodont .place.all .place.new .place.close] { $butt configure -pady 2 -border 1 -takefocus 0 } pack .place.yesdo .place.nodont .place.all .place.exp .place.up \ .place.down .place.match .place.new .place.close -in .place \ -side left -expand 1 -fill both pack .rep .with .place -in .replace -side top -expand 1 -fill both bind .rep.enter <Key-Return> {find_text replace} bind .with.leave <Key-Return> {find_text replace} bind .rep.enter <F3> {findwin {<br />}} bind .with.leave <F3> {findwin {<br />}} foreach {key star fin} {<F6> <p> </p> \ <F8> <i> </i> \ <F9> <b> </b> \ <Control-F6> <center> </center>} { bind .rep.enter $key "dualcodes $star {} $fin" bind .with.leave $key "dualcodes $star {} $fin" } bind .rep.enter <Button-1> {set foco .rep.enter} bind .with.leave <Button-1> {set foco .with.leave} grid .replace -row 1 -column 0 -columnspan 2 -sticky news } foreach butt [list .place.yesdo .place.nodont .place.all \ .place.new .place.close] { $butt configure -bg $::buttback -fg $::buttfore } foreach butt [list .place.exp .place.up .place.down .place.match] { $butt configure -selectcolor $::regradio } focus .rep.enter set foco .rep.enter set anytries 0 } # Procedure to get done with replacing: proc repdoon {} { global autotab oldautotab if {$oldautotab == 1} { set autotab 1 autotaborno } newfind replace clearin .fin clearin .replace } # Replace one instance at a time, with confirmation or disconfirmation proc replace_one {} { global place findlength searchway replacelength countum \ starting_place present_place search_reg replace_with currentfile .tx delete $place "$place + $countum chars" .tx insert $place $replace_with .tx edit separator wmtitle find_text replace } # Replace all instances, without confirmation proc replace_all {} { global replace_with search_for casematch expert selection clear set alltext [.tx get 1.0 end] set search_reg [regup $search_for] if {$casematch eq "nocase"} { set anysubs [regsub -all -nocase $search_reg $alltext\ $replace_with allsub] } else { set anysubs [regsub -all $search_reg $alltext $replace_with allsub] } if {$anysubs > 0} { .tx delete 1.0 end .tx insert 1.0 $allsub set finis "All matching text replaced" } else { set finis "No matching text found" } .fin.is configure -text $finis grid .fin -row 2 -column 0 -columnspan 2 -sticky news } ### Search -- Replace (Multiple) .filemenu.search add command -label "Replace (Multiple)" -underline 9 \ -command multirep -accelerator Ctrl+F3 bind . <Control-F3> multirep # Procedure to set up GUI box for multiple replace: proc multirep {} { global m n foco expert casematch set m 1 toplevel .mult wm title .mult "Replace (Multiple)" set n [expr $m-1] grid [label .mult.place($n) -text "Replace: "] \ -row $n -column 0 -sticky news grid [entry .mult.ent($n) -bg $::entback -fg $::entfore -width 60] \ -row $n -column 1 -sticky news if {[lsearch $::entlist ".mult.ent($n)"] < 0} { lappend ::entlist .mult.ent($n) } grid [label .mult.with($m) -text "with: "] \ -row $m -column 0 -sticky news grid [entry .mult.wix($m) -bg $::entback -fg $::entfore -width 60] \ -row $m -column 1 -sticky news if {[lsearch $::entlist ".mult.wix($m)"] < 0} { lappend ::entlist .mult.wix($m) } frame .mult.fr button .mult.more -text "Show More Pairs" -relief groove -border 3 \ -command morepairs checkbutton .mult.expert -text "Expert search" \ -selectcolor $::regradio -variable expert checkbutton .mult.match -text "Match case" -selectcolor $::regradio \ -variable casematch -onvalue exact -offvalue nocase button .mult.replall -text "Replace All" -command replall button .mult.close -text "Close" -takefocus 0 -command { set m 1 set n 0 destroy .mult focus .tx set foco .tx } foreach butt [list .mult.more .mult.replall .mult.close] { $butt configure -pady 2 -takefocus 0 -bg $::buttback -fg $::buttfore } pack .mult.more .mult.expert .mult.match .mult.replall \ .mult.close -in .mult.fr -side left -expand 1 -fill both morepairs focus .mult.ent(0) set foco .mult.ent(0) bind .mult <Key-Return> morepairs } # Procedure to add more entry widgets for multiple replace: proc morepairs {} { global m n foco expert incr m 2 set n [expr $m-1] grid forget .mult.fr grid [label .mult.place($n) -text "Replace: "] \ -row $n -column 0 -sticky news grid [entry .mult.ent($n) -bg $::entback -fg $::entfore -width 60] \ -row $n -column 1 -sticky news if {[lsearch $::entlist ".mult.ent($n)"] < 0} { lappend ::entlist .mult.ent($n) } grid [label .mult.with($m) -text "with: "] \ -row $m -column 0 -sticky news grid [entry .mult.wix($m) -bg $::entback -fg $::entfore -width 60] \ -row $m -column 1 -sticky news if {[lsearch $::entlist ".mult.wix($m)"] < 0} { lappend ::entlist .mult.wix($m) } grid .mult.fr -row [expr $m+1] -column 0 -columnspan 2 -sticky news if {$n > 2} { focus .mult.ent($n) set foco .mult.ent($n) } bind .mult <F3> {findwin {<br />}} foreach {key star fin} { <F6> <p> </p> \ <F8> <i> </i> \ <F9> <b> </b> \ <Control-F6> <center> </center> } {bind .mult $key "dualcodes $star {} $fin"} foreach i [range 0 to $m] { if {[winfo exists .mult.ent($i)]} { bind .mult.ent($i) <Button-1> "set foco .mult.ent($i)" } elseif {[winfo exists .mult.wix($i)]} { bind .mult.wix($i) <Button-1> "set foco .mult.wix($i)" } } } # Procedure to perform multiple replace: proc replall {} { global m n foco expert casematch set replist [list] set itall [.tx get 1.0 "end -1c"] foreach e [range 1 to $m 2] { set f [expr $e-1] set rep($f) [.mult.ent($f) get] set rep($e) [.mult.wix($e) get] if {$rep($f) ne ""} { lappend replist $rep($f) $rep($e) } } if {$expert == 0} { if {$casematch eq "exact"} { set newitall [string map "$replist" $itall] } else { set newitall [string map -nocase "$replist" $itall] } } else { set newitall $itall if {$casematch eq "exact"} { foreach e [range 1 to $m 2] { set f [expr $e-1] regsub -all "$rep($f)" $newitall "$rep($e)" newitall } } else { foreach e [range 1 to $m 2] { set f [expr $e-1] regsub -all -nocase "$rep($f)" $newitall "$rep($e)" newitall } } } .tx delete 1.0 "end -1c" .tx insert 1.0 $newitall .tx edit separator wmtitle focus .tx set foco .tx destroy .mult } .filemenu.search add separator # Search -- Line Number .filemenu.search add command -label "Line Number/Word Count" -underline 0 \ -command wordline -accelerator Ctrl+w bind . <Control-w> wordline # Procedure to find out what line number the cursor is on: proc line_number {} { global foco set herenow [$foco index insert] set lineno [expr int($herenow)] return $lineno } # Procedure to count words: proc wordcount {} { set wordsnow [.tx get 1.0 {end -1c}] set wordlist [split $wordsnow] set countnow 0 foreach item $wordlist { if {$item ne ""} { incr countnow } } return $countnow } # Set up "Line Number/Word Count" dialog bar: proc wordline {} { clearout if {[winfo exists .line]} { grid .line } else { frame .line label .line.goto -text "Go to line number: " -pady 2 entry .line.number -width 6 button .line.ok -text "GO" -relief groove -border 3 -command gotoline label .line.word -text "Word count: " -pady 2 label .line.count -relief sunken -width 12 -pady 2 button .line.recount -border 1 -text "Recount" -pady 2 \ -command recount button .line.close -border 1 -text "Close" -pady 2 -command { clearin .line } bind .line.number <Key-Return> gotoline pack .line.goto .line.number .line.ok .line.word .line.count \ .line.recount .line.close -in .line \ -side left -expand 1 -fill both grid .line -row 1 -column 0 -columnspan 2 -sticky news } .line.number configure -bg $::entback -fg $::entfore foreach butt [list .line.ok .line.recount .line.close] { $butt configure -bg $::buttback -fg $::buttfore } .line.count configure -bg $::lightback -fg $::lightfore recount } # Procedure to recount words and re-identify line number: proc recount {} { set lineno [line_number] .line.number delete 0 end .line.number insert 0 $lineno set linedigits [string length $lineno] .line.number selection range 0 $linedigits focus .line.number .line.count configure -text [wordcount] } # Procedure to go to another line, identified by number: proc gotoline {} { set newlineno [.line.number get] .tx mark set insert $newlineno.0 .tx see insert focus .tx set foco .tx } ### HTML MENU ### menu .filemenu.html -tearoff 0 .filemenu add cascade -label "HTML" -underline 2 -menu .filemenu.html # HTML -- Plain Text to HTML .filemenu.html add command -label "Plain Text to HTML" -underline 14 \ -command {convert_to_html plain} -accelerator Ctrl+H bind . <Control-H> {convert_to_html plain} .filemenu.html add command -label "Link-Text to HTML" -underline 7 \ -command {convert_to_html link} proc convert_to_html {what} { global converto lincoln linkhead set converto 1 if {$lincoln} { # Show codes, don't display Link-Text: set lincoln 0 unlink .tx } if {$what eq "link"} { set linkhead [.tx search "<end linkhead>" 1.0 end] if {$linkhead eq ""} { set linkhead 1.0 } # Find link beginnings and ends: if {$::tko > 8.4} { set linkstars [.tx search -regexp -all \ -count clink "<link .+?>" 1.0 end] set linkends [.tx search -all "</link>" 1.0 end] } else { set ::place 1.0 set ::linkline [list] set ::countline [list] set starlog [findtags "<link .+?>" ::linkline ::countline] set linkstars [lindex $starlog 0] set cti [lindex $starlog end] set ::place 1.0 set ::linkline [list] set ::countline [list] set endlog [findtags "</link>" ::linkline ::countline] set linkends [lindex $endlog 0] } # Make list of links; then temporarily hide them # so they won't be mistaken for their targets: .tx tag configure hide -elide 1 for {set i 0} {$i < [llength $linkstars]} {incr i} { set star [lindex $linkstars $i] ; # Begin link-start tag set starleng [lindex $clink $i] ; # Length of link-start tag set starsplit [split $star "."] set starline [lindex $starsplit 0] ; # Line number in text set starchar [lindex $starsplit end] ; # Position in line set starend $starline.[expr {$starchar + $starleng}] set linkstar [.tx get $star $starend] set linkname [string map "{link } {} {\"} {} {<} {} {>} {}" \ $linkstar] lappend linklist [list $starend "$linkname"] set finis [lindex $linkends $i] .tx tag add hide $star "$finis +7c" } # Search for targets and make a non-duplicative list of them: set targlist [list] set loclist [list] foreach link $linklist { set targ [lindex $link end] if {[lsearch $targlist $targ] == -1} { set linkloc [lindex $link 0] if {[.tx compare $linkloc < $linkhead]} { set target [.tx search -count ct "$targ" $linkhead end] } else { set target [.tx search -count ct "$targ" $linkloc end] if {$target eq ""} { set target [.tx search -backwards -count ct "$targ" \ $linkloc $linkhead] } } if {$target ne ""} { lappend targlist $targ lappend loclist [list $target $ct] } } } # Run backward through the list, # adding anchor codes all the way: set locleng [expr {[llength $loclist] -1}] foreach t [range $locleng to 0] { set targstar [lindex $loclist $t 0] set targleng [lindex $loclist $t end] set targname [lindex $targlist $t] set targend [.tx index "$targstar + $targleng chars"] .tx insert $targend "</a>" .tx insert $targstar "<a name=\"$targname\">" } } .tx tag delete hide set textutnunc [.tx get 1.0 {end -1c}] outwithold if {$what eq "link"} { set textutnunc [string map { "<link \"" "<a href=\"#"\ "</link>" "</a>"\ "<a name=\"" "<a name=\"" "\">" "\">" "&" "&"\ "?" "<"\ ">? ">"\ "\"" """\ "<end linkhead>" ""\ "<c>" "<center>"\ "</c>" "</center>"\ "<bi>" "<b><i>"\ "<ib>" "<i><b>"\ "<bc>" "<b><center>"\ "<cb>" "<center><b>"\ "<ic>" "<i><center>"\ "<ci>" "<center><i>"\ "</bi>" "</b></i>"\ "</ib>" "</i></b>"\ "</bc>" "</b></center>"\ "</cb>" "</center></b>"\ "</ic>" "</i></center>"\ "</ci>" "</center></i>"\ "<bic>" "<b><i><center>"\ "<bci>" "<b><center><i>"\ "<icb>" "<i><center><b>"\ "<ibc>" "<i><b><center>"\ "<cib>" "<center><i><b>"\ "<cbi>" "<center><b><i>"\ "</bic>" "</b></i></center>"\ "</bci>" "</b></center></i>"\ "</icb>" "</i></center></b>"\ "</ibc>" "</i></b></center>"\ "</cib>" "</center></i></b>"\ "</cbi>" "</center></b></i>"\ } $textutnunc] } else { set textutnunc [string map { "&" "&"\ "<" "<"\ ">" ">"\ "\"" """ } $textutnunc] } new_html .tx insert 18.0 $textutnunc\n set lastend [.tx index end] set lastnums [split $lastend .] set lastline [lindex $lastnums 0] set lastbutfour [expr $lastline - 4] .tx mark set insert 18.0 .tx insert 18.0 "<p>" set lineno [line_number] while {$lineno < $lastbutfour} { set endoline [.tx index "$lineno.0 lineend"] set isthisblank [expr $endoline - $lineno.0] set nextline [expr $lineno + 1] set endonext [.tx index "$nextline.0 lineend"] set isnextblank [expr $endonext - $nextline.0] if {$isthisblank ne 0.0 && $isnextblank eq 0.0} { .tx insert $endoline "</p>" } if {$isthisblank ne 0.0 && $isnextblank ne 0.0} { .tx insert $nextline.0 "<br />" } if {$isthisblank eq 0.0 && $isnextblank ne 0.0} { .tx insert $nextline.0 "<p>" } incr lineno } .tx mark set insert 9.0 .tx edit separator set converto 0 after 1000 wmtitle } .filemenu.html add separator # Procedure to tell whether to put HTML codes into # main text widget or HTML Table Data Entry box: # HTML -- Heading .filemenu.html add command -label "Heading" -underline 0 \ -command headingbox -accelerator Ctrl+F9 bind . <Control-F9> headingbox set headsize 1 # Procedure to set up heading selection dialog bar: proc headingbox {} { global headsize selon foco lastfoco autotab oldautotab set lastfoco $foco clearout if {$autotab == 1} { set oldautotab 1 set autotab 0 autotaborno } else { set oldautotab 0 } if {[winfo exists .head]} { grid .head } else { frame .head label .head.text -text "Heading Text: " entry .head.enter -width 50 set selon [catch {.tx get sel.first sel.last}] if {$selon == 0} { .head.enter insert insert [.tx get sel.first sel.last] } label .head.size -text "Heading size:" spinbox .head.spin -width 1 -from 1 -to 6 -textvariable headsize \ -buttonbackground $::buttback button .head.insert -text "Insert" -pady 2 -border 3 \ -relief groove -command headin button .head.close -text "Close" -pady 2 -border 1 -command doonhead bind . <Key-Return> headin bind .head <F3> {findwin {<br />}} foreach {key star fin} { <F6> <p> </p> \ <F8> <i> </i> \ <F9> <b> </b> \ <Control-F6> <center> </center>} { bind . $key "dualcodes $star {} $fin" } pack .head.text .head.enter .head.size .head.spin .head.insert \ .head.close -in .head -side left -expand 1 -fill both grid .head -row 1 -column 0 -columnspan 2 -sticky news } foreach ent [list .head.enter .head.spin] { $ent configure -bg $::entback -fg $::entfore } foreach butt [list .head.insert .head.close] { $butt configure -bg $::buttback -fg $::buttfore } focus .head.enter set foco .head.enter bind .head <FocusIn> {set foco .head.enter} } # Procedure for inserting heading and codes: proc headin {} { global headsize foco lastfoco set foco $lastfoco set cont [.head.enter get] dualcodes <h$headsize> "$cont" </h$headsize> .head.enter delete 0 end focus $foco } # Procedure to get done with headings: proc doonhead {} { global autotab oldautotab if {$oldautotab == 1} { set autotab 1 } autotaborno clearin .head } # HTML -- Font .filemenu.html add command -label "Font" -underline 0 \ -command fontbox -accelerator Ctrl+F8 bind . <Control-F8> fontbox set html_fontsize 0 set html_fontcolor "" set colorcall "" # Procedure to stop displaying font widgets: proc dumpboxes {} { global foco if {[winfo exists .colo]} {destroy .colo} clearin .font focus $foco } # Procedure to set up font selection dialog bar: proc fontbox {} { global colo html_fontsize html_fontcolor colorcall clearout if {[winfo exists .font]} { grid .font } else { frame .font label .font.size -text "Font size:" spinbox .font.spin -bg white -width 1 -textvariable html_fontsize \ -buttonbackground $::buttback -from "-2" -to 4 label .font.color -text "Font Color:" entry .font.colornum -width 10 -textvariable colo -bg white button .font.select -text "Select Color" -command { if {$colorcall ne ""} {set colorcall ""} wishcolor } button .font.insertcolor -text "Insert Color" \ -command insert_fontcolor button .font.insertsize -text "Insert size" \ -command insert_fontsize button .font.insertboth -text "Insert size + Color" \ -command insert_sizencolor button .font.close -text "Close" -command dumpboxes foreach butt [list .font.select .font.insertcolor .font.insertsize \ .font.insertboth .font.close] { $butt configure -padx 2 -borderwidth 1 } pack .font.size .font.spin .font.color .font.colornum .font.select \ .font.insertcolor .font.insertsize .font.insertboth .font.close \ -in .font -side left -expand 1 -fill both grid .font -row 1 -column 0 -columnspan 2 -sticky news } foreach ent [list .font.spin .font.colornum] { $ent configure -bg $::entback -fg $::entfore } foreach butt [list .font.select .font.insertcolor .font.insertsize \ .font.insertboth .font.close] { $butt configure -bg $::buttback -fg $::buttfore } focus .font.spin } # Procedure to insert font color in HTML code: proc insert_fontcolor {} { global colo html_fontcolor foco set html_fontcolor $colo dualcodes "<font color=\"$html_fontcolor\">" {} </font> } # Procedure to insert font size in HTML code: proc insert_fontsize {} { global html_fontsize foco if {$html_fontsize > 0} { set sizz "+$html_fontsize" } elseif {$html_fontsize < 0} { set size "-$html_fontsize" } dualcodes "<font size=\"$sizz\">" {} </font> } # Procedure to insert font size and color in HTML code: proc insert_sizencolor {} { global colo html_fontsize html_fontcolor foco if {$html_fontsize > 0} { set sizz "+$html_fontsize" } elseif {$html_fontsize < 0} { set sizz "-$html_fontsize" } set html_fontcolor $colo dualcodes "<font size=\"$sizz\"\ color=\"$html_fontcolor\">" {} </font> } .filemenu.html add separator # HTML -- Anchor .filemenu.html add command -label "Anchor" -underline 0 \ -command "anchorbox" -accelerator Ctrl+F7 bind . <Control-F7> anchorbox set lastanchor "" # Procedure to set up anchor insertion dialog bar: proc anchorbox {} { global lastanchor foco lastfoco autotab oldautotab if {$autotab == 1} { set oldautotab 1 set autotab 0 autotaborno } else { set oldautotab 0 } set lastfoco $foco clearout if {[winfo exists .anchor]} { grid .anchor } else { frame .anchor label .anchor.name -text "Anchor name: " entry .anchor.enter -width 64 -textvariable lastanchor if {[catch {.tx get sel.first sel.last}] == 0} { .anchor.enter insert insert [.tx get sel.first sel.last] } button .anchor.insert -text "Insert" -border 3 -relief groove \ -pady 2 -command insert_anchor button .anchor.close -text "Close" -border 1 -pady 2 \ -command anchordoon pack .anchor.name .anchor.enter .anchor.insert .anchor.close \ -in .anchor -side left -expand 1 -fill both bind .anchor <FocusIn> {set foco .anchor.enter} grid .anchor -row 1 -column 0 -columnspan 2 -sticky news bind . <Key-Return> insert_anchor } .anchor.enter configure -bg $::entback -fg $::entfore foreach butt [list .anchor.insert .anchor.close] { $butt configure -bg $::buttback -fg $::buttfore } focus .anchor.enter set foco .anchor.enter } # Procedure to insert anchor: proc insert_anchor {} { global lastanchor foco lastfoco set foco $lastfoco set cont [.anchor.enter get] dualcodes "<a name=\"$lastanchor\">" "$cont" </a> } # Procedure to get done with anchors: proc anchordoon {} { global autotab oldautotab if {$oldautotab == 1} { set autotab 1 } autotaborno clearin .anchor } # HTML -- Link .filemenu.html add command -label "Link" -underline 3 \ -command linkbox -accelerator F7 bind . <F7> linkbox set linktype "http://www." set textype html # Procedure to set up link entry dialog bar: proc linkbox {} { global linktype lastanchor foco lastfoco autotab oldautotab set lastfoco $foco if {$autotab == 1} { set oldautotab 1 set autotab 0 autotaborno } else { set oldautotab 0 } if {[winfo exists .link]} { grid .link .url.linkent insert 0 $linktype bind . <Key-Return> insert_link } else { frame .link frame .url label .url.urlink -text "Link to what? " entry .url.linkent -width 90 .url.linkent insert 0 $linktype pack .url.urlink .url.linkent -in .url \ -side left -expand 1 -fill both frame .show label .show.display -text "Display name: " entry .show.name -width 90 -bg white if {[catch {.tx get sel.first sel.last}] == 0} { .show.name insert insert [.tx get sel.first sel.last] } pack .show.display .show.name -in .show \ -side left -expand 1 -fill both frame .butt button .butt.www -text "WWW" -command { set textype html linkup "http://www." } button .butt.email -text "E-mail" -command { set textype html linkup "mailto:" } button .butt.ftp -text "FTP" -command { set textype html linkup "ftp://" } button .butt.anchor -text "Anchor" -command { set textype html linkup "#" } button .butt.linktext -text "Link-Text" -command { set textype link linkup "" } button .butt.other -text "Other" -command { set textype html linkup "" } button .butt.insert -text "Insert Link" -relief groove -border 3 \ -pady 2 -command insert_link button .butt.close -text "Close" -border 3 -relief groove \ -command linkdoon foreach butt [list .butt.www .butt.email .butt.ftp .butt.anchor \ .butt.linktext .butt.other .butt.close] { $butt configure -pady 0 -border 1 } foreach butt [list .butt.www .butt.email .butt.ftp .butt.anchor \ .butt.linktext .butt.other .butt.insert .butt.close] { pack $butt -in .butt -side left -expand 1 -fill both } bind . <Key-Return> insert_link bind .show.name <F3> {findwin {<br />}} foreach {key star fin} { <F6> <p> </p> \ <F8> <i> </i> \ <F9> <b> </b> \ <Control-F6> <center> </center>} { bind .show.name $key "dualcodes $star {} $fin"} bind .url.linkent <FocusIn> {set foco .url.linkent} bind .show.name <FocusIn> {set foco .show.name} pack .url .show .butt -in .link -side top -expand 1 -fill both grid .link -row 1 -column 0 -columnspan 2 -sticky news } foreach ent [list .url.linkent .show.name] { $ent configure -bg $::entback -fg $::entfore } foreach butt [list .butt.www .butt.email .butt.ftp .butt.anchor \ .butt.linktext .butt.other .butt.close] { $butt configure -bg $::buttback -fg $::buttfore } focus .url.linkent set foco .url.linkent } # Procedure to insert link prefix: proc linkup {prefix} { global linktype textype if {$linktype ne $prefix} { set linktype $prefix .url.linkent delete 0 end .show.name delete 0 end .url.linkent insert 0 $linktype focus .url.linkent } } # Procedure to insert link: proc insert_link {} { global linktype textype foco lastfoco set foco $lastfoco set link_id [.url.linkent get] set link_name [.show.name get] if {$textype eq "html"} { dualcodes "<a href=\"$link_id\">" "$link_name" </a> } else { dualcodes "<link \"$link_id\">" "$link_name" </link> } .url.linkent delete 0 end .show.name delete 0 end linkdoon } # Procedure to get done with links: proc linkdoon {} { global autotab oldautotab if {$oldautotab == 1} { set autotab 1 } autotaborno clearin .link } .filemenu.html add separator # HTML -- Image .filemenu.html add command -label "Image" -underline 1 \ -command imagebox -accelerator Ctrl+F11 bind . <Control-F11> imagebox # Procedure for setting up image insertion box: proc imagebox {} { global alignimage imagedir image_hspace image_vspace imageheight \ imagewidth imagebordo imagepath imagedir dirurl foco lastfoco if {[info exists imagepath] == 0} { set imagepath relative } if {[info exists alignimage] == 0} { set alignimage left } if {[info exists dirurl] == 0} { set dirurl "" } foreach var [list image_hspace image_vspace imageheight \ imagewidth imagebordo] {set $var 0} set lastfoco $foco if {[winfo exists .image]} {destroy .image} toplevel .image wm title .image "Insert Image Source" grid [label .image.dest -text "Directory URL:" -pady 6] \ -row 0 -column 0 -sticky news grid [entry .image.url -bg white -textvariable dirurl] \ -row 0 -column 1 -columnspan 2 -sticky news if {$imagepath eq "relative"} { foreach widget [list .image.dest .image.url] { $widget configure -state disabled } } else { foreach widget [list .image.dest .image.url] { $widget configure -state normal } } grid [label .image.filename -text "Image file name:" -pady 6] \ -row 1 -column 0 -sticky news grid [entry .image.enter -width 56 -bg white] \ -row 1 -column 1 -columnspan 2 -sticky news frame .image.fr2 button .image.pick -text "Pick Image" -command pickimage label .image.path -text "Path to Image: " -pady 6 radiobutton .image.rel -text "Relative" -variable imagepath \ -value "relative" -selectcolor $::regradio -command { foreach widget [list .image.dest .image.url] { $widget configure -state disabled } focus .image.enter } radiobutton .image.abso -text "Absolute" -variable imagepath \ -value "absolute" -selectcolor $::regradio -command { foreach widget [list .image.dest .image.url] { $widget configure -state normal } focus .image.url } label .image.align -text "Align:" pack .image.pick .image.path .image.rel .image.abso .image.align \ -in .image.fr2 -side left -expand 1 -fill both grid .image.fr2 -row 2 -column 0 -columnspan 2 -sticky news tk_optionMenu .image.lineup alignimage left right top middle bottom grid .image.lineup -row 2 -column 2 -sticky news grid [label .image.optinfo -bg $::lightback -fg $::lightfore \ -text "O P T I O N A L I N F O R M A T I O N :" -pady 6] \ -row 3 -column 0 -columnspan 3 -sticky news grid [label .image.alt -text "Image description:" -pady 6] \ -row 4 -column 0 -sticky news grid [entry .image.altinhere -width 56 -bg white] \ -row 4 -column 1 -columnspan 2 -sticky news frame .image.fr5 label .image.horspace -text "Spacing: Horiz" -pady 6 spinbox .image.horizhere -width 4 -bg white \ -buttonbackground $::buttback \ -textvariable image_hspace -from 0 -to 1000 label .image.vertspace -text " Vert" spinbox .image.vertinhere -width 4 -bg white \ -buttonbackground $::buttback\ -textvariable image_vspace -from 0 -to 1000 label .image.height -text " Height" spinbox .image.heightinhere -width 5 -bg white \ -buttonbackground $::buttback\ -textvariable imageheight -from 0 -to 10000 label .image.width -text " Width" spinbox .image.widthinhere -width 5 -bg white \ -buttonbackground $::buttback \ -textvariable imagewidth -from 0 -to 10000 label .image.bordo -text " Border" spinbox .image.bordohere -width 3 -bg white \ -buttonbackground $::buttback \ -textvariable imagebordo -from 0 -to 100 pack .image.horspace .image.horizhere .image.vertspace .image.vertinhere \ .image.height .image.heightinhere .image.width .image.widthinhere \ .image.bordo .image.bordohere -in .image.fr5 \ -side left -expand 1 -fill both grid .image.fr5 -row 5 -column 0 -columnspan 3 -sticky news frame .image.fr6 button .image.insert -text "Insert" -default active \ -command insert_image button .image.close -text "Close" -default normal -command { focus .tx set foco .tx destroy .image } pack .image.insert .image.close -in .image.fr6 \ -side left -expand 1 -fill both grid .image.fr6 -row 6 -column 0 -columnspan 3 -sticky news bind .image <Key-Return> insert_image if {$imagepath eq "relative"} { focus .image.enter set foco .image.enter } else { focus .image.url set foco .image.url } foreach ent [list .image.url .image.enter .image.altinhere] { bind $ent <FocusIn> "set foco $ent" } foreach ent [list .image.url .image.enter .image.altinhere \ .image.horizhere .image.vertinhere .image.heightinhere \ .image.widthinhere .image.bordohere ] { $ent configure -bg $::entback -fg $::entfore } foreach butt [list .image.insert .image.close] { $butt configure -bg $::buttback -fg $::buttfore } } # Procedure to pick image file name: proc pickimage {} { global imagepath foco currentfile if {$currentfile ne ""} { set imagedir [file dirname $currentfile] } else { set imagedir [pwd] } set imagefile [tk_getOpenFile -title "Pick Image File" \ -initialdir $imagedir] set imagename [file tail $imagefile] .image.enter insert 0 $imagename focus .image.enter set foco .image.enter } # Procedure to insert image source into HTML code: proc insert_image {} { global alignimage codestart codend image_hspace image_vspace \ imageheight imagewidth imagebordo foco imagepath dirurl lastfoco set foco $lastfoco set img_src [.image.enter get] if {$imagepath eq "absolute" && [regexp "$dirurl" $img_src] == 0} { set dirurl [string trimright $dirurl "/"] set img_src $dirurl/$img_src } set alttext [.image.altinhere get] if {$alttext ne ""} { set alttext " alt=\"$alttext\"" } if {$image_hspace > 0} { set imhup " hspace=\"$image_hspace\"" } else { set imhup "" } if {$image_vspace > 0} { set imvup " vspace=\"$image_vspace\"" } else { set imvup "" } if {$imageheight > 0} { set imhut " height=\"$imageheight\"" } else { set imhut "" } if {$imagewidth > 0} { set imgwid " width=\"$imagewidth\"" } else { set imgwid "" } if {$imagebordo > 0} { set imbord " border=\"$imagebordo\"" } else { set imbord "" } $foco insert insert \ "<img src=\"$img_src\"\ align=\"$alignimage\"$alttext$imhup$imvup$imhut$imgwid$imbord>" $foco edit separator if {$foco eq ".tx"} { wmtitle } foreach var [list image_hspace image_vspace imageheight \ imagewidth imagebordo] {set $var 0} destroy .image } .filemenu.html add separator # HTML -- List .filemenu.html add command -label "List" -underline 2 \ -command html_list -accelerator F11 bind . <F11> html_list set listtype 1 set liston 0 set ordo 1 # Procedure to set up dialog bar for list item entry: proc html_list {} { global listtype liston foco lastfoco autotab oldautotab if {$autotab == 1} { set oldautotab 1 set autotab 0 autotaborno } else { set oldautotab 0 } if {[winfo class $foco] eq "Text"} { set lastfoco $foco } else { set lastfoco .tx } if {$liston == 1} {set liston 0} if {[winfo exists .html_list]} { grid .html_list } else { frame .html_list frame .html label .html.item -text "List item: " entry .html.itemhere -width 72 -bg white if {[catch {$foco get sel.first sel.last}] == 0} { .html.itemhere insert insert [$foco get sel.first sel.last] } button .html.insert -text "Insert" -relief groove -border 3 \ -pady 2 -command insert_item button .html.done -text "Done" -border 1 -pady 2 \ -command finish_list pack .html.item .html.itemhere .html.insert .html.done \ -in .html -side left -expand 1 -fill both frame .list label .list.style -text "Style: " radiobutton .list.123 -text "1-2-3" -variable listtype -value 1 radiobutton .list.capa -text "A-B-C" -variable listtype -value A radiobutton .list.abc -text "a-b-c" -variable listtype -value a radiobutton .list.capi -text "I-II-III" -variable listtype -value I radiobutton .list.iii -text "i-ii-iii" -variable listtype -value i radiobutton .list.disc -text "Discs" -variable listtype -value disc radiobutton .list.circle -text "Circles" -variable listtype \ -value circle radiobutton .list.square -text "Squares" -variable listtype \ -value square pack .list.style .list.123 .list.capa .list.abc .list.capi .list.iii \ .list.disc .list.circle .list.square -in .list \ -side left -expand 1 -fill both pack .list .html -in .html_list -side top -expand 1 -fill both grid .html_list -row 1 -column 0 -columnspan 2 -sticky news bind .html_list <FocusIn> {set foco .html.itemhere} bind .html.itemhere <Key-Return> insert_item bind .html_list <F3> {findwin {<br />}} foreach {key star fin} { <F6> <p> </p> \ <F8> <i> </i> \ <F9> <b> </b> \ <Control-F6> <center> </center> } {bind .html_list $key "dualcodes $star {} $fin"} } .html.itemhere configure -bg $::entback -fg $::entfore foreach butt [list .html.insert .html.done] { $butt configure -bg $::buttback -fg $::buttfore } foreach reg [list .list.123 .list.capa .list.abc .list.capi \ .list.iii .list.disc .list.circle .list.square] { $reg configure -selectcolor $::regradio } focus .html.itemhere set foco .html.itemhere } # Procedure to create list and insert items: proc insert_item {} { global listchoice listtype liston ordo foco lastfoco set list_item [.html.itemhere get] if {[catch {$lastfoco get sel.first sel.last}] == 0} { $lastfoco delete sel.first sel.last } if {$liston == 0} { switch $listtype { 1 - A - a - I - i { set ordo 1 } disc - circle - square { set ordo 0 } } if { $ordo == 1 } { $lastfoco insert insert \ "<ol type=$listtype>\n\t<li>$list_item</li>\n" } else { $lastfoco insert insert \ "<ul type=$listtype>\n\t<li>$list_item</li>\n" } set liston 1 } else { $lastfoco insert insert "\t<li>$list_item</li>\n" } .html.itemhere delete 0 end $lastfoco edit separator wmtitle focus .html.itemhere set foco .html.itemhere } # Procedure to finish off list: proc finish_list {} { global ordo foco lastfoco autotab oldautotab if {$ordo == 1} { $lastfoco insert insert "</ol>\n\n" } else { $lastfoco insert insert "</ul>\n\n" } set liston 0 set foco $lastfoco $foco edit separator if {$foco eq ".tx"} { wmtitle } clearin .html_list if {$oldautotab == 1} { set autotab 1 autotaborno } } # HTML -- Table .filemenu.html add command -label "Table: Create" -underline 0 \ -command tablebox -accelerator F12 bind . <F12> tablebox .filemenu.html add command -label "Table: Continue" -underline 8 -command { set rowon 0 set celltype Data .tx insert insert "\n\t" databox } -accelerator Ctrl+F12 bind . <Control-F12> { set rowon 0 set celltype Data .tx insert insert "\n\t" databox } # Initialize variables for table attributes: foreach var [list tableon tablesum table_hspace table_vspace tableheight \ tablewidth tablebordo cellpad cellspace] {set $var 0} set tablecolor "" # Procedure to create Table Setup box: proc tablebox {} { global color tablecolor blankrows blankcols tablesum table_hspace \ table_vspace tableheight tablewidth tablebordo cellpad cellspace \ tablecolor celltype foco if { [winfo exists .table] } { destroy .table } toplevel .table wm title .table "HTML Table Setup" grid [button .table.withdata -text "M A K E T A B L E" \ -default active -bg $::buttback -fg $::buttfore -command { get_tablecodes make_table set celltype Header databox destroy .table }] -row 0 -column 0 -columnspan 7 -sticky news grid [button .table.close -text "Close" -default normal \ -bg $::buttback -fg $::buttfore -command { destroy .table focus .tx set foco .tx }] -row 0 -column 7 -columnspan 5 -sticky news grid [label .table.optinfo -bg $::lightback -fg $::lightfore \ -text "O P T I O N A L I N F O R M A T I O N :" -pady 6] \ -row 1 -column 0 -columnspan 11 -sticky news grid [label .table.sum -text "Table summary:" -pady 6] \ -row 2 -column 0 -columnspan 2 -sticky news grid [entry .table.suminhere -width 40] \ -row 2 -column 2 -columnspan 9 -sticky news grid [label .table.horspace -text "Spacing: Horiz" -pady 6] \ -row 3 -column 0 -columnspan 2 -sticky news grid [spinbox .table.horizhere -width 4 \ -buttonbackground $::buttback \ -textvariable table_hspace -from 0 -to 1000] \ -row 3 -column 2 -sticky news grid [label .table.vertspace -text "Vert"] \ -row 3 -column 3 -sticky news grid [spinbox .table.vertinhere -width 4 -bg white \ -buttonbackground $::buttback \ -textvariable table_vspace -from 0 -to 1000] \ -row 3 -column 4 -sticky news grid [label .table.height -text "Height"] \ -row 3 -column 5 -sticky news grid [spinbox .table.heightinhere -width 5 -bg white \ -buttonbackground $::buttback \ -textvariable tableheight -from 0 -to 10000] \ -row 3 -column 6 -sticky news grid [label .table.width -text "Width"] \ -row 3 -column 7 -sticky news grid [spinbox .table.widthinhere -width 5 -bg white \ -buttonbackground $::buttback \ -textvariable tablewidth -from 0 -to 10000] \ -row 3 -column 8 -sticky news grid [label .table.bordo -text "Border"] \ -row 3 -column 9 -sticky news grid [spinbox .table.bordohere -width 3 -bg white \ -buttonbackground $::buttback \ -textvariable tablebordo -from 0 -to 100] \ -row 3 -column 10 -sticky news grid [label .table.cellpad -text "Space inside cells" -pady 6] \ -row 4 -column 0 -columnspan 2 -sticky news grid [spinbox .table.padhere -width 3 -bg white \ -buttonbackground $::buttback \ -textvariable cellpad -from 0 -to 100] \ -row 4 -column 2 -sticky news grid [label .table.cellspace -text "Space between cells"] \ -row 4 -column 3 -columnspan 3 -sticky news grid [spinbox .table.spacehere -width 3 -bg white \ -buttonbackground $::buttback \ -textvariable cellspace -from 0 -to 100] \ -row 4 -column 6 -sticky news grid [label .table.allinpixels -text "(all in pixels)"] \ -row 4 -column 7 -columnspan 4 -sticky news grid [label .table.tablecolor -text "Background color:"] \ -row 5 -column 0 -columnspan 2 -sticky news grid [label .table.colorcode -textvariable color] \ -row 5 -column 2 -columnspan 2 -sticky news grid [button .table.colorsel -text "Select color" -command { if {$colorcall ne ""} {set colorcall ""} wishcolor }] -row 5 -column 4 -columnspan 3 -sticky news grid [button .table.colordesel -text "Deselect color" \ -command { set color "" }] \ -row 5 -column 7 -columnspan 4 -sticky news bind .table <Key-Return> { get_tablecodes ; make_table ; databox ; destroy .table } foreach ent [list .table.suminhere .table.horizhere .table.vertinhere \ .table.heightinhere .table.widthinhere .table.bordohere \ .table.padhere .table.spacehere] { $ent configure -bg $::entback -fg $::entfore } foreach butt [list .table.withdata .table.close .table.colorsel \ .table.colordesel] { $butt configure -bg $::buttback -fg $::buttfore } focus .table.suminhere set foco .table.suminhere bind .table.suminhere <FocusIn> {set foco .table.suminhere} } # Procedure to get HTML codes for table attributes from user input: proc get_tablecodes {} { global blankcols blankrows color tablecolor table_hspace table_vspace \ tableheight tablewidth tablebordo cellpad cellspace tablesum \ tabhup tabvup tabhut tabwid tabbord tabcol celpa celspa set tablesum [.table.suminhere get] if {$color ne ""} { set tablecolor $color set tabcol " bgcolor=\"$tablecolor\"" } else { set tabcol "" } if {$tablesum ne ""} { set tablesum " summary=\"$tablesum\"" } if {$table_hspace > 0} { set tabhup " hspace=\"$table_hspace\"" } else { set tabhup "" } if {$table_vspace > 0} { set tabvup " vspace=\"$table_vspace\"" } else { set tabvup "" } if {$tableheight > 0} { set tabhut " height=\"$tableheight\"" } else { set tabhut "" } if {$tablewidth > 0} { set tabwid " width=\"$tablewidth\"" } else { set tabwid "" } if {$tablebordo > 0} { set tabbord " border=\"$tablebordo\"" } else { set tabbord "" } if {$cellpad > 0} { set celpa " cellpadding=\"$cellpad\"" } else { set celpa "" } if {$cellspace > 0} { set celspa " cellspacing=\"$cellspace\"" } else { set celspa "" } } # Procedure to insert HTML codes for beginning and end of table: proc make_table {} { global tabcol table_hspace table_vspace horowin vertrowin rowcolor \ tableheight tablewidth tablebordo cellpad cellspace tablesum \ tabhup tabvup tabhut tabwid tabbord celpa celspa .tx insert insert \ "<table$tablesum$tabcol$tabhup$tabvup\ $tabhut$tabwid$tabbord$celpa$celspa>\n\n\n\n</table>" set lineno [expr int([.tx index insert])] .tx mark set insert [expr $lineno-2].0 .tx insert insert "\t" .tx edit separator wmtitle } # Initialize variables for row attributes: set horowalign left set vertrowalign middle set horowin "" set vertrowin "" set rowcolor "" set rowon 0 # Initialize variables for cell attributes: set horcellalign left set vertcellalign middle set horcellin "" set vertcellin "" set rowspannum 1 set colspannum 1 set rowcolor "" set cellcolor "" # Procedure to create HTML Table Data Entry box: proc databox {} { global horowalign vertrowalign horcellalign \ vertcellalign colspannum rowspannum textbox \ color rowcolor cellcolor celltype colorcall fonto foco toplevel .data wm title .data "HTML Table Data Entry" grid [label .data.cellcont -text "C E L L C O N T E N T S :" \ -bg $::lightback -fg $::lightfore -pady 6] \ -row 0 -column 0 -columnspan 6 -sticky news frame .data.but1 button .data.line -text "New Line (F3)" -command { .data.cont insert insert "\n<br />" .data.cont edit separator .data.cont see insert } button .data.par -text "New Par (F6)" foreach {butt star fin} {<FocusIn> {\n<p>} {</p>}} { bind .data.par $butt "dualcodes $star {} $fin" } button .data.ital -text "Italic (F8)" -command { dualcodes <i> {} </i> } button .data.bold -text "Bold (F9)" -command { dualcodes <b> {} </b> } set insbutts [list .data.line .data.par .data.ital .data.bold] foreach butt $insbutts { $butt configure -pady 0 -padx 0 -borderwidth 1 \ -bg $::buttback -fg $::buttfore pack $butt -in .data.but1 -side left -expand 1 -fill both } grid .data.but1 -row 1 -column 0 -columnspan 6 -sticky news frame .data.but2 button .data.ins -text "Insert" -command { set openins Insert set foco .data.cont openrece file } bind .data <Control-comma> { set openins Insert set foco .data.cont openrece file } button .data.cut -text "Cut" -command { set foco .data.cont cut_text } bind .data <Control-x> { set foco .data.cont cut_text } button .data.copy -text "Copy" -command { set foco .data.cont copy_text } bind .data <Control-c> { set foco .data.cont copy_text } button .data.paste -text "Paste" -command { set foco .data.cont paste_text } bind .data <Control-g> { set foco .data.cont paste_text } bind .data <Control-X> { set foco .data.cont supercut } bind .data <Control-C> { set foco .data.cont supercopy } bind .data <F1> {openrece paste} button .data.undo -text "Undo" -command { catch {.data.cont edit undo} } button .data.redo -text "Redo" -command { catch {.data.cont edit redo} } button .data.special -text "Special" -command specialbox set databutts [list .data.ins .data.cut .data.copy .data.paste \ .data.undo .data.redo .data.special] foreach butt $databutts { $butt configure -pady 0 -padx 0 -borderwidth 1 \ -bg $::buttback -fg $::buttfore pack $butt -in .data.but2 -side left -expand 1 -fill both } grid .data.but2 -row 2 -column 0 -columnspan 6 -sticky news frame .data.tx text .data.cont -bg $::textback -fg $::textfore -width 44 \ -height 8 -font $fonto -wrap word -setgrid 1 -undo 1 \ -inactiveselectbackground $::inacback scrollbar .data.roll -width 12 -command ".data.cont yview" .data.cont configure -yscrollcommand ".data.roll set" pack .data.cont .data.roll -in .data.tx \ -side left -expand 1 -fill both grid .data.tx -row 3 -column 0 -columnspan 6 -sticky news grid [label .data.celltype -text "Cell type:"] \ -row 4 -column 0 -sticky news tk_optionMenu .data.cellmenu celltype Header Data grid .data.cellmenu -row 4 -column 1 -sticky news grid [label .data.colspan -text "Column span:"] \ -row 4 -column 2 -sticky news grid [spinbox .data.colspannum -width 3 -bg $::entback -fg $::entfore \ -buttonbackground $::buttback \ -textvariable colspannum -from 1 -to 100] \ -row 4 -column 3 -sticky news grid [label .data.rowspan -text "Row span:"] \ -row 4 -column 4 -sticky news grid [spinbox .data.rowspannum -width 3 -bg $::entback -fg $::entfore \ -buttonbackground $::buttback \ -textvariable rowspannum -from 1 -to 100] \ -row 4 -column 5 -sticky news frame .data.fr1 button .data.enter -text "Enter" -default active \ -command insert_cell button .data.newrow -text "Begin new row" -default normal \ -command newrow button .data.done -text "Done" -default normal -command { if {$rowon == 1} { .tx insert insert "\t</tr>\n" } set rowon 0 destroy .data } button .data.close -text "Close" -default normal -command { destroy .data focus .tx set foco .tx } foreach butt [list .data.enter .data.newrow .data.done .data.close] { $butt configure -bg $::buttback -fg $::buttfore pack $butt -in .data.fr1 -side left -expand 1 -fill both } grid .data.fr1 -row 5 -column 0 -columnspan 6 -sticky news grid [label .data.optinfo -bg $::lightback -fg $::lightfore \ -text "O P T I O N A L I N F O R M A T I O N :" -pady 6] \ -row 6 -column 0 -columnspan 6 -sticky news grid [label .data.rowalign -text "Align in row:"] \ -row 7 -column 0 -sticky news grid [label .data.horowalign -text "Horizontal" ] \ -row 7 -column 1 -sticky news tk_optionMenu .data.horowmenu horowalign left center right grid .data.horowmenu -row 7 -column 2 -sticky news grid [label .data.vertrowalign -text "Vertical"] \ -row 7 -column 3 -sticky news tk_optionMenu .data.vertrowmenu vertrowalign \ top middle bottom baseline grid .data.vertrowmenu -row 7 -column 4 -columnspan 2 -sticky news grid [label .data.cellalign -text "Align in cell:"] \ -row 8 -column 0 -sticky news grid [label .data.horcellalign -text "Horizontal" ] \ -row 8 -column 1 -sticky news tk_optionMenu .data.horcellmenu horcellalign left center right grid .data.horcellmenu -row 8 -column 2 -sticky news grid [label .data.vertcellalign -text "Vertical"] \ -row 8 -column 3 -sticky news tk_optionMenu .data.vertcellmenu vertcellalign \ top middle bottom baseline grid .data.vertcellmenu -row 8 -column 4 -columnspan 2 -sticky news frame .data.froth frame .data.frow button .data.rowcolorsel -text "Select row color" -command { set colorcall row wishcolor } button .data.rowcolordesel -text "Deselect row color" -command { set color "" set rowcolor "" } pack .data.rowcolorsel .data.rowcolordesel -in .data.frow \ -side top -expand 1 -fill both frame .data.frell button .data.cellcolorsel -text "Select cell color" -command { set colorcall cell wishcolor } button .data.cellcolordesel -text "Deselect cell color" -command { set color "" set cellcolor "" } pack .data.cellcolorsel .data.cellcolordesel -in .data.frell \ -side top -expand 1 -fill both pack .data.frow .data.frell -in .data.froth -side left -expand 1 -fill both grid .data.froth -row 9 -column 0 -columnspan 6 -sticky news foreach butt [list .data.rowcolorsel .data.rowcolordesel \ .data.cellcolorsel .data.cellcolordesel] { $butt configure -bg $::buttback -fg $::buttfore } bind .data <Key-Return> insert_cell bind .data <F3> { .data.cont insert insert "\n<br />" .data.cont edit separator .data.cont see insert } foreach {key star fin} { <F6> {\n<p>} {</p>} \ <F8> <i> </i> \ <F9> <b> </b> \ <Control-F6> <center> </center> } {bind .data $key "dualcodes $star {} $fin"} bind .data <Control-r> { catch {.data.cont edit redo} } bind .data <space> {.data.cont edit separator} bind .data <BackSpace> {.data.cont edit separator} focus .data.cont set foco .data.cont bind .data <FocusIn> {set foco .data.cont} } # Procedure to get HTML codes for row attributes from user input # ("left" and "middle" are defaults for # horizontal and vertical alignment of contents): proc get_rowcodes {} { global horowalign vertrowalign vertrowin horowin rowcolor if {$horowalign eq "left"} { set horowin "" } else { set horowin " align=\"$horowalign\"" } if {$vertrowalign eq "middle"} { set vertowin "" } else { set vertrowin " valign=\"$vertrowalign\"" } if {$rowcolor ne ""} { set rowcolor " bgcolor=\"$rowcolor\"" } } # Procedure to get HTML codes for cell attributes from user input: proc get_cellcodes {} { global colspannum rowspannum horcellalign vertcellalign \ horcellin vertcellin cellcolor rowspa colspa if {$rowspannum > 1} { set rowspa " rowspan=\"$rowspannum\"" } else { set rowspa "" } if {$colspannum > 1} { set colspa " colspan=\"$colspannum\"" } else { set colspa "" } if {$horcellalign eq "left"} { set horcellin "" } else { set horcellin " align=\"$horcellalign\"" } if {$vertcellalign == "middle"} { set vertcellin "" } else { set vertcellin " valign=\"$vertcellalign\"" } if {$cellcolor ne ""} { set cellcolor " bgcolor=\"$cellcolor\"" } } # Procedure to insert new data cell in existing row of HTML table: proc insert_cell {} { global codestart codend colspannum rowspannum horowin vertrowin \ horcellin vertcellin rowcolor cellcolor celltype rowon \ colspa rowspa set cellcontents [string trimright [.data.cont get 1.0 end-1c]] if {$rowon == 0} { get_rowcodes get_cellcodes .tx insert insert "<tr$horowin$vertrowin$rowcolor>\n" set rowon 1 } else { get_cellcodes } if {$celltype eq "Header"} { set star "\t\t<th$colspa$rowspa$horcellin$vertcellin$cellcolor>" set fin "</th>\n" } else { set star "\t\t<td$colspa$rowspa$horcellin$vertcellin$cellcolor>" set fin "</td>\n" } .tx insert insert $star$cellcontents$fin .tx edit modified wmtitle set lineno [line_number] set downfour [expr $lineno + 4] .tx see $downfour.0 .data.cont delete 1.0 end focus .data.cont } # Procedure to insert new row in HTML table with data contents: proc newrow {} { global celltype horowin vertrowin rowcolor rowon if {$celltype eq "Header"} {set celltype Data} get_rowcodes if {$rowon == 1} { .tx insert insert \ "\t</tr>\n\n\t<tr$horowin$vertrowin$rowcolor>\n" } else { .tx insert insert "\n\t<tr$horowin$vertrowin$rowcolor>\n" } if {$rowon == 0} {set rowon 1} set lineno [line_number] .tx see [expr $lineno+3].0 .tx edit separator wmtitle } .filemenu.html add separator # HTML -- Paragraph .filemenu.html add command -label "Paragraph <p>" -underline 0 -command { dualcodes "<p>" {} </p> } -accelerator F6 bind . <F6> {dualcodes "<p>" {} "</p>"} # HTML -- Line Break .filemenu.html add command -label "Line Break <br>" -underline 0 -command { .tx insert insert "<br />" .tx edit separator .tx see insert wmtitle } -accelerator F3 bind . <F3> { .tx insert insert "<br />" .tx edit separator .tx see insert wmtitle } # HTML -- Emphasis .filemenu.html add command -label "Italics <i>" -underline 0 -command { dualcodes <i> {} </i> } -accelerator F8 bind . <F8> {dualcodes <i> {} </i>} # HTML -- Strong .filemenu.html add command -label "Bold <b>" -underline 0 -command { dualcodes <b> {} </b> } -accelerator F9 bind . <F9> {dualcodes <b> {} </b>} # HTML -- Center .filemenu.html add command -label "Center <center>" -underline 5 -command { dualcodes <center> {} </center> } -accelerator Ctrl+F6 bind . <Control-F6> {dualcodes <center> {} </center>} ### TCL/TK MENU ### menu .filemenu.tcl -tearoff 0 .filemenu add cascade -label "Tcl/Tk" -underline 0 -menu .filemenu.tcl # Tcl/Tk -- New Script .filemenu.tcl add command -label "New Script" -underline 0 \ -command new_wish -accelerator Ctrl+F5 bind . <Control-F5> new_wish proc new_wish {} { set go [readytogo] if {$go == 0} {return} outwithold .tx insert 1.0 "#!/usr/bin/env wish\n\n# " .tx edit separator wmtitle } .filemenu.tcl add separator # Tcl/Tk -- Run Selected Code .filemenu.tcl add command -label "Run Selected Code" -underline 0 \ -command runcode -accelerator F5 bind . <F5> runcode proc runcode {} { if {[interp exists testrunner]} {interp delete testrunner} set anysel [catch {.tx get sel.first sel.last} codetorun] if {$anysel == 0} { interp create testrunner load {} Tk testrunner testrunner eval $codetorun } else { tk_messageBox -message "Please select some code to run" \ -title "Select Code" -type ok } } .filemenu.tcl add separator # Tcl/Tk -- Find Closing .filemenu.tcl add command -label "Find Closing" -underline 0 \ -command findclose -accelerator Ctrl+Alt+\[ bind . <Control-Alt-bracketleft> findclose proc findclose {} { global lev ope clo whence whither here # Find what to search for and where to search from: if {[catch {set ope [.tx get sel.first sel.last]}]} { set ope "" } set whence [.tx index sel.last] set whither "" set lev 1 ; # Opening found, closing not yet found switch $ope { "\{" { set clo "\}" } "\[" { set clo "\]" } "\"" { set clo $ope } default { tk_messageBox -message "Please select an opening\ brace ( \{ ), bracket ( \[ ), or quote ( \" )" -type ok return } } set here $whence findmatch if {$lev == 0 && $whither ne ""} { .tx tag add sel $whence $whither } else { tk_messageBox -message "Closing not found" -type ok } } proc findmatch {} { global lev ope clo whence whither here if {$clo eq $ope} { set whereat [.tx search $clo $whence end] } else { set up [.tx search $ope $here end] set down [.tx search $clo $here end] if {$up eq ""} { set whichendup down set whereat $down } if {$down eq ""} { set whereat "" } if {$up ne "" && $down ne ""} { if {[.tx compare $up > $down]} { set whichendup down set whereat $down } else { set whichendup up set whereat $up } } } if {$whereat ne ""} { set whatbefore [.tx get "$whereat -1c"] if {$whatbefore eq "\\"} { set here [.tx index "$whereat +1c"] findmatch } else { if {$clo eq $ope} { set whither [.tx index "$whereat +1c"] set lev 0 return } else { set here [.tx index "$whereat +1c"] if {$whichendup eq "up"} { incr lev } else { incr lev -1 } } } } if {$lev == 0} { set whither $here return } elseif {$whereat ne ""} { findmatch } } .filemenu.tcl add separator # Tcl/Tk -- Matching Braces { } .filemenu.tcl add command -label "Curly Braces \{ \}" -underline 0 -command { dualcodes "{" {} "}" } -accelerator Ctrl+\{ bind . <Control-braceleft> {dualcodes "{" {} "}"} bind . <Shift-Home> { .tx mark set insert "[.tx index insert] lineend" .tx insert insert " " .tx insert insert "\{\}" .tx mark set insert "insert -1c" selection clear } .filemenu.tcl add command -label "Next Braces" -underline 2 -command { .tx mark set insert "[.tx index insert] lineend" .tx insert insert " " .tx insert insert "\{\}" .tx mark set insert "insert -1c" selection clear } -accelerator Shift+Home .filemenu.tcl add command -label "Leave Braces" -underline 0 -command { autotab stop } -accelerator Shift+Enter .filemenu.tcl add separator # Tcl/Tk -- Matching Brackets [ ] .filemenu.tcl add command -label "Square Brackets \[ \]" \ -underline 0 -command { dualcodes {[} {} {]} } -accelerator Ctrl+\[ bind . <Control-bracketleft> {dualcodes {[} {} {]}} # Tcl/Tk -- Matching Angle Brackets < > .filemenu.tcl add command -label "Angle Brackets < >" \ -underline 0 -command { dualcodes {<} {} {>} } -accelerator Ctrl+< bind . <Control-less> {dualcodes {<} {} {>}} # Tcl/Tk -- Matching Parentheses ( ) .filemenu.tcl add command -label "Parentheses ( )" \ -underline 0 -command { dualcodes {(} {} {)} } -accelerator Ctrl+( bind . <Control-parenleft> {dualcodes {(} {} {)}} # Tcl/Tk -- Matching Quotes " " .filemenu.tcl add command -label "Quotes \" \"" \ -underline 0 -command { dualcodes {"} {} {"} } -accelerator Ctrl+\" bind . <Control-quotedbl> {dualcodes {"} {} {"}} ### DISPLAY MENU ### menu .filemenu.display -tearoff 0 .filemenu add cascade -label "Display" -underline 0 -menu .filemenu.display ### Display -- Format/Window size .filemenu.display add command -label "Format/Window Size" -underline 1 \ -command formato # Procedures to format text with newlines: proc formato {} { global texwid texhi oldwid oldhi formawid set oldwid $texwid ; set oldhi $texhi clearout if {[winfo exists .forma]} { grid .forma } else { frame .forma label .forma.hi -text "Height: " spinbox .forma.disphi -from 1 -to 100 -textvariable texhi \ -buttonbackground $::buttback -width 3 label .forma.wid -text "Window width: " spinbox .forma.dispwid -from 20 -to 200 -textvariable texwid \ -buttonbackground $::buttback -width 3 label .forma.form -text "Format to width: " spinbox .forma.formawid -from 20 -to 200 -textvariable formawid \ -buttonbackground $::buttback -width 3 button .forma.chug -text "Resize window" -command { .tx configure -height $texhi -width $texwid wm geometry . {} savefig } button .forma.ok -text "Format" -command {formatit show} button .forma.close -text "Close" -command { set texwid $oldwid set texhi $oldhi clearin .forma } pack .forma.hi .forma.disphi .forma.wid .forma.dispwid \ .forma.form .forma.formawid .forma.chug .forma.ok .forma.close \ -in .forma -side left -expand 1 -fill both grid .forma -row 1 -column 0 -columnspan 2 -sticky news } foreach spin [list .forma.disphi .forma.dispwid .forma.formawid] { $spin configure -bg $::entback -fg $::entfore } foreach butt [list .forma.chug .forma.ok .forma.close] { $butt configure -bg $::buttback -fg $::buttfore } } proc formatit {whattodo} { global formawid texwid wordwrap printorshow clearin .forma if {[winfo exists .tinga] == 0} { grid [label .tinga -text "Formatting ... may take a while for\ long text .... Please wait"] \ -row 1 -column 0 -columnspan 2 -sticky news } if {$whattodo eq "print"} { set printout [formanew print] destroy .tinga return $printout } else { .tx configure -width $formawid -wrap word wm geometry . {} after 100 { formanew show destroy .tinga .tx configure -width $texwid -wrap $wordwrap wm geometry . {} } } } proc formanew {whattodo} { global formawid # Identify beginning and end of text to format, and # omit needless newlines: omitneedless plus if {[.tx tag ranges sel] eq ""} { set selon 1.0 set seloff [.tx index end] } else { set selon [.tx index sel.first] set seloff [.tx index sel.last] } set texin [expr int($selon)] set texend [expr int($seloff)] # Initialize variable to hold output: set formatext "" # Dig in and format text: for {set i $texin} {$i <= $texend} {incr i} { # Get text to newline: set endolin [.tx index $i.end] set endochar [lindex [split $endolin "."] end] set whatline [.tx get $i.0 $endolin] # If line is blank, insert only newline into output: if {[string trim $whatline] eq ""} { append formatext "\n" continue } # If not, then find out where line is wrapped: for {set c 1} {$c <= $endochar} {incr c} { .tx see $i.$c set ceemin [expr {$c-1}] set boxie [.tx get $i.$ceemin] # Get y coordinates of bounding boxes for adjoining characters: set pixy [lindex [.tx bbox $i.$ceemin] 1] set nexy [lindex [.tx bbox $i.$c] 1] # If y coordinate of bounding box is greater than for # preceding character, line has been wrapped, so # insert preceding character plus newline into output: if {$nexy > $pixy} { append formatext $boxie\n .tx see $i.$c } else { # Otherwise, insert only the preceding character: append formatext $boxie } } # Replicate existing newline from text widget: if {$i < $texend} { append formatext "\n" } } if {$whattodo eq "print"} { return $formatext } else { .tx delete $selon $seloff .tx insert $selon $formatext .tx edit separator after 100 wmtitle } } .filemenu.display add command -label "Omit Needless Newlines" -underline 5 \ -command newlino ### Procedures to omit needless newlines: proc newlino {} { global reunito parsep clearout if {[winfo exists .need]} { grid .need } else { frame .need radiobutton .need.unite -text "Reunite broken words" \ -variable reunito -value 1 radiobutton .need.replace -text "No broken words" \ -variable reunito -value 0 checkbutton .need.par -text "Keep paragraphs separate" \ -variable parsep button .need.ok -text "Eject needless newlines" -command { omitneedless only clearin .need } button .need.close -text "Close" -pady 0 -border 1 \ -command { clearin .need } pack .need.unite .need.replace .need.par .need.ok \ .need.close -in .need -side left -expand 1 -fill both grid .need -row 1 -column 0 -columnspan 2 -sticky news } foreach reg [list .need.unite .need.replace .need.par] { $reg configure -selectcolor $::regradio -takefocus 0 } foreach butt [list .need.ok .need.close] { $butt configure -bg $::buttback -fg $::buttfore } focus .need } proc omitneedless {andwhat} { global reunito parsep if {[.tx tag ranges sel] eq ""} { set selon 1.0 set seloff [.tx index end] set selmore 0 } else { set selon [.tx index sel.first] set seloff [.tx index sel.last] set selmore 1 } set texin [expr int($selon)] set texend [expr int($seloff)] set texauld [.tx get $selon $seloff] switch "$reunito $parsep" { "1 1" { set texnoo [string map "{\n\n} {\n\n} {\n\t} {\n\t} {\n} {}"\ $texauld] } "1 0" { set texnoo [string map "{\n} {}" $texauld] } "0 1" { set texnoo [string map "{\n\n} {\n\n} {\n\t} {\n\t}\ { \n} { } {\n} { }" $texauld] } "0 0" { set texnoo [string map "{ \n} { } {\n} { }" $texauld] } } .tx delete $selon $seloff .tx insert $selon $texnoo if {$selmore == 1 && $andwhat eq "plus"} { .tx tag add sel $selon [.tx index insert] } .tx edit separator after 100 wmtitle } .filemenu.display add separator ### Display -- HTML in Browser .filemenu.display add command -label "HTML in Browser" -underline 0 \ -command {browsier $currentfile} proc browsier {fil} { global env currentfile if {$fil eq ""} { tk_messageBox -message "Please save HTML file before trying\ to display it in a browser" -type ok return } if {$env(BROWSER) ne ""} { if {[catch {eval exec $env(BROWSER) $currentfile &} outage]} { tk_messageBox -message $outage -type ok } } else { browbox } } ### Display -- Change Browser .filemenu.display add command -label "Change Browser" -underline 7 \ -command browbox proc browbox {} { global env clearout if {[winfo exists .brow]} { grid .brow .brow.ent delete 0 end .brow.ent insert 0 $env(BROWSER) .brow.ent selection range 0 end focus .brow.ent } else { frame .brow label .brow.blab -bg $::headback -fg $::headfore \ -text "Please designate a browser: " entry .brow.ent -bg $::entback -fg $::entfore .brow.ent insert 0 $env(BROWSER) .brow.ent selection range 0 end button .brow.ok -bg $::buttback -fg $::buttfore -text "OK" -command { set env(BROWSER) [.brow.ent get] clearin .brow } button .brow.close -bg $::buttback -fg $::buttfore -text "Close" \ -command {clearin .brow} pack .brow.blab .brow.ent .brow.ok .brow.close -in .brow \ -side left -expand 1 -fill both grid .brow -row 1 -column 0 -columnspan 2 -sticky news focus .brow.ent } } .filemenu.display add separator ### Display -- Colors .filemenu.display add command -label "Colors" -underline 0 -command colodisp # List of widgets (to add to lists originally set # by WISH Color Picker Plus): # Regular buttons: foreach butt [list .rece.find .rece.open .rece.all .rece.whole \ .rece.unlist .rece.close .prin.ok .prin.close .forma.chug .forma.ok \ .forma.close .need.ok .need.close .fin.clo .find.next .findex.new \ .findex.close .place.yesdo .place.nodont .place.all .place.new \ .place.close .mult.more .mult.replall .mult.close .line.ok \ .line.recount .line.close .head.insert .head.close .font.select \ .font.insertcolor .font.insertsize .font.insertboth .font.close \ .anchor.insert .anchor.close .butt.www .butt.email .butt.ftp \ .butt.anchor .butt.other .butt.insert .butt.close .image.pick \ .image.insert .image.close .html.insert .html.done .table.withdata \ .table.close .table.colorsel .table.colordesel .data.line \ .data.par .data.ital .data.bold .data.undo .data.redo .data.special \ .data.enter .data.newrow .data.done .data.close .data.rowcolorsel \ .data.rowcolordesel .data.cellcolorsel .data.cellcolordesel \ .see.ins .see.close .fontshow.ok .fontshow.close] { lappend buttlist $butt } # Mini-toolbar buttons: foreach mini $miniline { lappend minilist $mini } # Listboxes: foreach lub [list .rece.list .fontshow.list] { lappend lublist $lub } # Text widgets: foreach tex [list .tx .see.whole .data.cont] { lappend texlist $tex } # Entry widgets and spinboxes: foreach ent [list .rece.ent .rece.spin .prin.spin .forma.disphi \ .forma.dispwid .forma.formawid .find.enter .rep.enter .with.leave \ .line.number .head.enter .head.spin .font.spin .font.colornum \ .anchor.enter .url.linkent .show.name .image.url .image.altinhere \ .image.horizhere .image.vertinhere .image.heightinhere .image.widthinhere \ .image.bordohere .html.itemhere .table.suminhere .table.horizhere \ .table.vertinhere .table.heightinhere .table.widthinhere .table.bordohere \ .table.padhere .table.spacehere .data.colspannum .data.rowspannum \ .fontshow.spin] { lappend entlist $ent } # Emphasized labels: foreach head [list] { lappend headlist $head } # Light labels: foreach light [list .rece.found .line.count .image.optinfo .table.optinfo \ .data.cellcont .data.optinfo .fontshow.lab] { lappend lightlist $light } # Radiobuttons and checkbuttons: foreach reg [list .rece.new .need.unite .need.replace .need.par \ .findex.exp .findex.match .findex.up .findex.down .place.exp \ .place.up .place.down .place.match .mult.expert .mult.match \ .image.rel .image.abso .list.123 .list.capa .list.abc .list.capi \ .list.iii .list.disc .list.circle .list.square] { lappend regradiolist $reg } # Spinbox buttons: foreach spin [list .rece.spin .prin.spin .head.spin .font.spin \ .image.horizhere .image.vertinhere .image.heightinhere \ .image.widthinhere .image.bordohere .table.horizhere \ .table.vertinhere .table.heightinhere .table.widthinhere \ .table.bordohere .table.padhere .table.spacehere \ .data.colspannum .data.rowspannum .fontshow.spin .forma.disphi \ .forma.dispwid .forma.formawid] { lappend spinlist $spin } # Procedure to set up GUI box for configuring color display: proc colodisp {} { global color red green blue whatfig whatbutt colorlist \ winback winfore selback selfore buttback buttfore miniback minifore \ listback listfore textback textfore inacback linktex entback \ entfore headback headfore lightback lightfore regradio wishcolorplus ; # This does all the work--from WISH Color Picker Plus wm title .colo "WISH Supernotepad : WISH Color Picker Plus" } ### Display -- Font .filemenu.display add command -label "Font" -underline 0 -command fontshow # List available fonts: set fontlist [lsort -dictionary [font families]] # Procedure to make font selection box: proc fontshow {} { global fontlist fontgrip fonto siz fontaine toplevel .fontshow wm title .fontshow "WISH Supernotepad: Choose Font" set fontgrip $fonto grid [listbox .fontshow.list -bg $::listback -fg $::listfore -height 12 \ -width 52 -selectmode single -listvariable fontlist] \ -row 0 -column 0 -sticky news grid [scrollbar .fontshow.roll -width 12 -command ".fontshow.list yview"] \ -row 0 -column 1 -rowspan 2 -sticky news .fontshow.list configure -yscrollcommand ".fontshow.roll set" set siz 14 bind .fontshow.list <Button-1> { after 10 { set fontgrip [.fontshow.list get [.fontshow.list curselection]] set fontaine [list $fontgrip $siz] .fontshow.lab configure -text "$fontgrip" -font "$fontaine" } } bind .fontshow.list <Double-Button-1> fontok bind .fontshow.list <Button-3> { set clixel %y set clickline [.fontshow.list nearest $clixel] .fontshow.list selection set $clickline set fontgrip [.fontshow.list get [.fontshow.list curselection]] set fontaine [list $fontgrip $siz] .fontshow.lab configure -text "$fontgrip" -font "$fontaine" fontok } frame .fontshow.butts label .fontshow.lab -bg $::lightback -fg $::lightfore \ -text "$fonto" -font "$fontaine" spinbox .fontshow.spin -textvariable siz -width 2 -from 8 -to 48 \ -buttonbackground $::buttback \ -bg $::entback -fg $::entfore -command { set fontaine [list $fontgrip $siz] .fontshow.lab configure -font "$fontaine" } button .fontshow.ok -text "OK" -bg $::buttback -fg $::buttfore \ -relief groove -border 3 -command fontok button .fontshow.close -text "Close" -bg $::buttback -fg $::buttfore \ -command {destroy .fontshow} pack .fontshow.lab .fontshow.spin .fontshow.ok .fontshow.close \ -in .fontshow.butts -side left -expand 1 -fill both grid .fontshow.butts -row 1 -column 0 -sticky news bind .fontshow <Key-Return> fontok focus .fontshow.spin } # Procedure to apply and save new default font: proc fontok {} { global t fontgrip fonto siz fontaine linkup set fonto $fontgrip set fontaine [list $fonto $siz] .tx configure -font "$fontaine" $t tag configure bold -font "[list $::fonto $::siz bold]" $t tag configure ital -font "[list $::fonto $::siz italic]" $t tag configure bi -font "[list $::fonto $::siz bold italic]" $t tag configure cent -justify center $t tag configure boldcent -font "[list $::fonto $::siz bold]" \ -justify center $t tag configure italcent -font "[list $::fonto $::siz italic]" \ -justify center $t tag configure bicent -font "[list $::fonto $::siz bold italic]" \ -justify center savefig destroy .fontshow } .filemenu.display add separator ### Display -- Link-Text .filemenu.display add checkbutton -label "Link-Text" -underline 0 \ -variable lincoln -accelerator Ctrl+Alt+l -command linkuporno bind .tx <Control-Alt-l> { if {$lincoln} { set lincoln 0 unlink .tx } else { set lincoln 1 linktext .tx } } # Procedure to put Link-Text tags in or take them out: proc linkuporno {} { global lincoln if {$lincoln} { linktext .tx } else { unlink .tx } } # Procedure to find markup tags with Tk 8.4, which doesn't have # the "-all" flag for text-widget searches as Tk 8.5 does: proc findtags {what lister counter} { set ::present_place $::place catch {set ::place [.tx search -regexp \ -count countum "$what" "$::present_place +1c" end]} if {$::place ne ""} { lappend $lister $::place lappend $counter $countum findtags $what } else { return [list [set $lister] [set $counter]] } } # Procedure to make clickable links, hide markup tags, # and show text as bold, italic, and/or centered: proc linktext {t} { global linklist linkex linkhead # Configure tag to hide things: $t tag configure hide -elide 1 # Find end of opening "link section" of file, # beginnings and ends of all links, and # beginnings of bold, italic, and/or center tags: set linkhead [$t search "<end linkhead>" 1.0 end] if {$linkhead ne ""} { $t tag add hide $linkhead "$linkhead +14c" } if {$::tko > 8.4} { # First find angle quotes (?) used to disguise angle brackets # that are *not* to be interpreted as designating tags, # and whip up a quick disguise: set angstars [$t search -all "?" 1.0 end] set angends [$t search -all ">? 1.0 end] $t tag configure ang -elide 1 foreach star $angstars { $t tag add hide $star $t tag add ang "$star +1c" } foreach end $angends { $t tag add ang $end $t tag add hide "$end +1c" } # Find link beginnings and ends: set linkstars [$t search -regexp -all \ -count clink "<link .+?>" 1.0 end] set linkends [$t search -all "</link>" 1.0 end] # Find tag beginnings and ends: set tagstars [$t search -regexp -all -count ctag { <bi?c?>|<bc?i?>|<ib?c?>|<ic?b?>|<cb?i?>|<ci?b?>|<center> } 1.0 end] # Now reveal the non-tag-designating angle brackets: $t tag configure ang -elide 0 } else { # Delete this clunky code if you don't need Tk 8.4 any more set ::place 1.0 set ::angline [list] set starlog [findtags "?<" ::angline] set angstars [lindex $starlog 0] set :: place 1.0 set ::angline [list] set endlog [findtags "\>? ::angline] set angends [lindex $endlog 0] $t tag configure ang -elide 1 foreach star $angstars { $t tag add hide $star $t tag add ang "$star +1c" } foreach end $angends { $t tag add ang $end $t tag add hide "$end +1c" } set ::place 1.0 set ::linkline [list] set ::countline [list] set starlog [findtags "<link .+?>" ::linkline ::countline] set linkstars [lindex $starlog 0] set cti [lindex $starlog end] set ::place 1.0 set ::linkline [list] set ::countline [list] set endlog [findtags "</link>" ::linkline ::countline] set linkends [lindex $endlog 0] set ::place 1.0 set ::taglist [list] set ::tagcount [list] set startag [findtags { <bi?c?>|<bc?i?>|<ib?c?>|<ic?b?>|<cb?i?>|<ci?b?>|<center> } ::taglist ::tagcount] set tagstars [lindex $startag 0] set ctag [lindex $startag end] $t tag configure ang -elide 0 unset ::linkline ::countlist ::boldlist ::bountlist ::angline } # Embolden, italicize, and/or center: $t tag configure bold -font "[list $::fonto $::siz bold]" $t tag configure ital -font "[list $::fonto $::siz italic]" $t tag configure bi -font "[list $::fonto $::siz bold italic]" $t tag configure cent -justify center $t tag configure boldcent -font "[list $::fonto $::siz bold]" \ -justify center $t tag configure italcent -font "[list $::fonto $::siz italic]" \ -justify center $t tag configure bicent -font "[list $::fonto $::siz bold italic]" \ -justify center for {set b 0} {$b < [llength $tagstars]} {incr b} { set bar [lindex $tagstars $b] ; # Begin starting tag set barsplit [split $bar "."] set barline [lindex $barsplit 0] ; # Line number in text set barchar [lindex $barsplit end] ; # Position in line set tagoff [$t search ">" $bar end] $t tag add hide $bar "$tagoff +1c" set whattag [$t get "$bar +1c" $tagoff] switch $whattag { b { set tagend [$t search "</b>" $tagoff end] $t tag add hide $tagend "$tagend +4c" $t tag add bold $tagoff $tagend } i { set tagend [$t search "</i>" $tagoff end] $t tag add hide $tagend "$tagend +4c" $t tag add ital $tagoff $tagend } c { set tagend [$t search "</c>" $tagoff end] $t tag add hide $tagend "$tagend +4c" $t tag add cent $tagoff $tagend } center { set tagend [$t search "</center>" $tagoff end] $t tag add hide $tagend "$tagend +9c" $t tag add cent $tagoff $tagend } bi - ib { set tagend [$t search -regexp {</bi>|</ib>} $tagoff end] $t tag add hide $tagend "$tagend +5c" $t tag add bi $tagoff $tagend } bc - cb { set tagend [$t search -regexp {</bc>|</cb>} $tagoff end] $t tag add hide $tagend "$tagend +5c" $t tag add boldcent $tagoff $tagend } ic - ci { set tagend [$t search -regexp {</ic>|</ci>} $tagoff end] $t tag add hide $tagend "$tagend +5c" $t tag add italcent $tagoff $tagend } bic - ibc - bci - cbi - icb - cib { set tagend [$t search -regexp { </bic>|</ibc>|</bci>|</cbi>|</icb>|</cib> } $tagoff end] $t tag add hide $tagend "$tagend +6c" $t tag add bicent $tagoff $tagend } } } # Fix the links up to work: $t configure -cursor top_left_arrow for {set i 0} {$i < [llength $linkstars]} {incr i} { set star [lindex $linkstars $i] ; # Begin link-start tag set starleng [lindex $clink $i] ; # Length of link-start tag set starsplit [split $star "."] set starline [lindex $starsplit 0] ; # Line number in text set starchar [lindex $starsplit end] ; # Position in line # End of link-start tag: set starend $starline.[expr {$starchar + $starleng}] # Content of link-start tag: set linkstar [$t get $star $starend] set linkname [string trim $linkstar "<>"] ; # Link name $t tag add hide $star $starend # Add tag for clickable link between link-start and link-end tags: set finis [lindex $linkends $i] $t tag add $linkname $starend $finis lappend linklist "$linkname" # And one to hide the link-end tag: $t tag add hide $finis "$finis +7c" # Get clickable tag to look right and do things: $t tag configure $linkname -foreground blue -underline 1 $t tag bind $linkname <ButtonRelease-1> "linkfind $t" } } # Procedure to search for link name in text: proc linkfind {t} { global linkhead # See where clicked link is: set clickpos [$t index insert] # Verify that it's really a link: set tagnames [$t tag names $clickpos] set tagplace [lsearch $tagnames "link *"] if {$tagplace > -1} { # If so, strip off everything but its name: set tagname [lindex $tagnames $tagplace] set searchname [string map "{link } {} {\"} {}" $tagname] # And find where the name appears in the text: if {$linkhead ne ""} { set target [$t search "$searchname" $linkhead end] } else { set tagend [lindex [$t tag range "$tagname"] end] set target [$t search "$searchname" $tagend end] if {$target eq ""} { set target [$t search -backwards "$searchname" $tagend end] } } if {$target ne ""} { $t see $target } else { tk_messageBox -message "Link \"$searchname\" not found" -type ok } } } # Procedure to undo Link-Text display: proc unlink {t} { global linklist $t tag delete bold ital bi cent boldcent italcent bicent hide ang foreach link $linklist { $t tag delete "$link" } $t configure -cursor xterm } .filemenu.display add separator ### Display -- Word Wrap .filemenu.display add checkbutton -variable wordwrap \ -label "Word wrap" -onvalue word -offvalue none \ -underline 0 -selectcolor blue -command wraponoroff proc wraponoroff {} { global wordwrap if {$wordwrap eq "none"} { .tx configure -wrap none } else { .tx configure -wrap word } } ### HELP MENU ### menu .filemenu.help -tearoff 0 .filemenu add cascade -label "Help" -underline 0 -menu .filemenu.help set helpfile [file join $docdir superhelp_link.txt] ; # User Help Guide set licfile [file join $docdir mule_license.txt] ; # License ### Help -- About WISH Supernotepad .filemenu.help add command -label "About WISH Supernotepad" \ -underline 0 -command { tk_messageBox -message "WISH Supernotepad $version\n\ by David McClamrock\n <[email protected]>\n\n\ Based on Tk NotePad 0.5.0\n by Joseph Acosta\n\ and \"textedit.tcl\"\n by Eric Foster-Johnson\n"\ -title "About WISH Supernotepad" -type ok } .filemenu.help add separator ### Help -- User Help .filemenu.help add command -label "User Help" -underline 0 -command superhelp # Procedure for setting up user help display proc superhelp {} { global fonto siz set oldfonto $fonto set oldsiz $siz uhelp ; # Set up user help window wm title .uhelp "WISH Supernotepad - User Help" # set helplink [open $::helpfile r] set helplink [open /home/david/9.com/wish/suite/superhelp_link.txt r] set helpcontents [read $helplink] close $helplink .uhelp.tx insert 1.0 $helpcontents linktext .uhelp.tx ; # Show links in text set fonto $oldfonto set siz $oldsiz .uhelp.tx see 1.0 } # Procedure for making user help window # (Color variables come from WISH Color Picker Plus) proc uhelp {} { global helpfont helpsiz fonto siz set fonto $helpfont set siz $helpsiz toplevel .uhelp wm title .uhelp "WISH User Help" frame .uhelp.fr0 button .uhelp.find -text "Find (F2)" -bg $::buttback -fg $::buttfore \ -command findhelp entry .uhelp.lookup -width 40 -bg $::entback -fg $::entfore pack .uhelp.find .uhelp.lookup -in .uhelp.fr0 \ -side left -expand 1 -fill both grid .uhelp.fr0 -sticky news frame .uhelp.fr1 text .uhelp.tx -width 65 -height 25 -bg $::textback -fg $::textfore \ -font "[list $helpfont $helpsiz]" -wrap word -cursor top_left_arrow scrollbar .uhelp.scrolly -width 12 -command ".uhelp.tx yview" .uhelp.tx configure -yscrollcommand ".uhelp.scrolly set" .uhelp.tx tag configure bold -font "[list $helpfont $helpsiz bold]" .uhelp.tx tag configure ital -font "[list $helpfont $helpsiz italic]" .uhelp.tx tag configure bi -font "[list $helpfont $helpsiz bold italic]" .uhelp.tx tag configure boldcent -font "[list $helpfont $helpsiz bold]" \ -justify center .uhelp.tx tag configure italcent -font "[list $helpfont $helpsiz italic]" \ -justify center .uhelp.tx tag configure bicent -font "[list $helpfont $helpsiz\ bold italic]" -justify center pack .uhelp.tx .uhelp.scrolly -in .uhelp.fr1 \ -side left -expand 1 -fill both grid .uhelp.fr1 -sticky news frame .uhelp.fr2 button .uhelp.big -text "Bigger" -command {fontsize big} button .uhelp.small -text "Smaller" -command {fontsize small} button .uhelp.close -text "Close" -command {destroy .uhelp} foreach butt [list .uhelp.big .uhelp.small .uhelp.close] { $butt configure -bg $::buttback -fg $::buttfore } pack .uhelp.big .uhelp.small .uhelp.close -in .uhelp.fr2 \ -side left -expand 1 -fill both grid .uhelp.fr2 -sticky news bind .uhelp <F2> findhelp focus .uhelp.lookup } # Procedure for changing font size in user help display: proc fontsize {how} { global helpfont helpsiz set sizzes [list 10 12 14 18 24] set siznow [lsearch $sizzes $helpsiz] if {$how eq "big" && $siznow < 4} { set helpsiz [lindex $sizzes [expr {$siznow+1}]] } if {$how eq "small" && $siznow > 0} { set helpsiz [lindex $sizzes [expr {$siznow-1}]] } if {$helpsiz == 10} { .uhelp.small configure -state disabled } else { .uhelp.small configure -state normal } if {$helpsiz == 24} { .uhelp.big configure -state disabled } else { .uhelp.big configure -state normal } .uhelp.tx configure -font "[list $helpfont $helpsiz]" .uhelp.tx tag configure bold -font "[list $helpfont $helpsiz bold]" .uhelp.tx tag configure ital -font "[list $helpfont $helpsiz italic]" .uhelp.tx tag configure bi -font "[list $helpfont $helpsiz bold italic]" .uhelp.tx tag configure boldcent -font "[list $helpfont $helpsiz bold]" \ -justify center .uhelp.tx tag configure italcent -font "[list $helpfont $helpsiz italic]" \ -justify center .uhelp.tx tag configure bicent -font "[list $helpfont $helpsiz\ bold italic]" -justify center } # Procedure for searching for user help text proc findhelp {} { set startout [.uhelp.tx index insert] set wherenow $startout set look_for [.uhelp.lookup get] set stringlength [string length $look_for] set foundit [.uhelp.tx search -nocase -forward $look_for \ $wherenow end] if {$foundit == ""} { set wherenow $startout tk_messageBox -message "Not Found" \ -title "Not Found" -type ok } else { catch {.uhelp.tx tag remove sel sel.first sel.last} .uhelp.tx tag add sel $foundit "$foundit + $stringlength chars" .uhelp.tx mark set insert "$foundit + $stringlength chars" .uhelp.tx see insert focus .uhelp.tx } } ### GET GOING ### # At last, make the menu visible: . configure -menu .filemenu # Open file from the command line, if you wish: if {[info exists argv]} { if {[file readable [lindex $argv 0]]} { set newfile [lindex $argv 0] inwithnew .tx mark set insert 1.0 set currentfile $newfile saverece .tx edit separator wmtitle } }