Here's a little OS X 10.x utility that explores an FB^3-generated
Aqua GUI interface on a Unix utility and database. The
forward/reverse button handling could stand some work-- suggestions
invited.
Let me know what you think. Bug reports, criticisms, comments welcomed.
Ken
p.s. Please watch for e-mail line breaks and lost constant
underscores on the Associate server.
/*
OS X Word Finder
A obscure piece of OS X trivia is that each
version ships with a list of all the words
in Webster's 2nd International Dictionary
(234,936 of them to be precise).
This little utility allows you to search
that database by entering at least three
characters from any word. (Searching for
one- or two letter- combinations is possible,
but unwieldly.) OS X Word Finder returns all
the words that contain the letter combination
entered. OS X Word Finder uses the Unix "grep"
utility to parse its response into an array.
The operation is extremely quick.
Example: Entering the letters "ine"
returns a list of 5,384 words containing
that three-letter combination.
I wrote this as an exercise to combine
Unix functions with a pleasant FB^3 GUI.
Due to FB^3's 32K edit field size limitation,
lists in excess of 500 words are displayed
500 at a time.
Ken Shmidheiser
Somerset, KY
11-3-02
*/
#if ( CarbonLib == 0 ) or ( ndef _appearanceRuntime )
compile shutdown "Must be compiled as Appearance Compliant with Carbon"
#endif
output file "OS X Word Finder"
begin globals
dim dynamic dictStr( _maxLong ) as str63
dim as container gC
dim as integer gDirection
end globals
DEF FN UBound(@P AS PTR) = [P + _AutoXREFCurr] - 1
local fn BuildMenus
apple menu "About OS X Word Finder"
menu 1, 0, _enable, "File"
menu 1, 1, _enable, "Find word"
gFBEditSelectAll = _zTrue
edit menu 2
end fn
local fn AboutWindow
dim as str255 infoStr
dim as rect r
setrect( r, 0, 0, 250, 160 )
appearance Window -2, "About Word Finder", @r,¬
_kDocumentWindowClass, _kWindowStandardFloatingAttributes
def SetWindowBackground( _kThemeActiveDialogBackgroundBrush,_zTrue)
text _sysFont, 16, _boldbit%, _srcCopy
color _zRed
setrect( r, 20, 20, 230, 60 )
edit field -10,, @r, _statNoFramed,_centerJust
infoStr = CHR$(13) + "OS X Word Finder" + CHR$(13)
edit$(10) = infoStr
text _applFont, 12, 0,_srcCopy
setrect( r, 20, 70, 230, 140 )
color _zBlack
edit field -11,, @r, _statNoFramed,_centerJust
infoStr = +"Coded in FB^3 by Ken Shmidheiser" + CHR$(13)¬
+ "Somerset, KY" + CHR$(13) + "November 3, 2002"
edit$(11) = infoStr
def windowreposition( 2, 1, _kWindowAlertPositionOnParentWindowScreen )
window 2
end fn
local fn AlphaFilter
dim as str15 keyStr
dim as str63 testStr
keyStr = tekey$
testStr = edit$(9)
long if testStr[0] < 26
long if testStr[0] < 25// enable alpha keys
IF keyStr >= "a" and keyStr<= "z" then tekey$ = keyStr
IF keyStr >= "A" and keyStr<= "Z" then tekey$ = keyStr
end if
select case asc ( keyStr )
case 28, 29// enable arrow keys
tekey$ = keyStr
case 8, 127// enable delete keys
tekey$ = keyStr
end select
xelse
beep
end if
end fn
local fn BuildWindow
dim as pointer @ filterFN
dim as rect r
setrect( r, 0, 0 , 450, 340 )
appearance Window -1, "OS X Word Finder", @r,¬
_kDocumentWindowClass, _kWindowStandardFloatingAttributes
def SetWindowBackground(_kThemeActiveDialogBackgroundBrush,_zTrue)
edit = 4
text _monaco, 12
setrect( r, 242, 15, 430, 30)
edit field 8,"Enter 3 or more letters:",@r,_statNoFramed,_leftJust
setrect( r, 245, 40, 430, 55)
filterFN = @fn AlphaFilter
edit field 9, "", @r, _framedNoCr, _leftJust, filterFN
setrect( r, 20, 20, 214, 280)
edit field 10,"",@r,_copyOnlyFramed,_leftJust
setrect( r, 214, 16, 230, 284)
scroll button -10,0,0,0,0, @r, _scrollOther
setrect( r, 240, 70, 430, 105)
edit field 11,"",@r,_statNoFramed,_leftJust
setrect( r, 340, 300, 435, 320)
button 1, 1, "Find word", @r, _shadow
setrect( r, 20, 300, 120, 320)
appearance button 2, 1, 0, 0, 1, "<‹ Previous 500",¬
@r, _kControlBevelButtonSmallBevelProc
setrect( r, 130, 300, 230, 320)
appearance button 3, 1, 0, 0, 1, "Next 500 ‹>",¬
@r, _kControlBevelButtonSmallBevelProc
appearance button -2
appearance button -3
edit field 9
window 1
end fn
local fn FindDictionaryWords( wordStr as str63 )
dim as str255 wStr
dim as integer i
wStr = "grep " + wordStr + " /usr/share/dict/words"
i = 0
OPEN "UNIX", 2, wStr
DO
LINE INPUT #2, wStr
dictStr(i) = wStr
i++
UNTIL EOF (2)
CLOSE 2
compress dynamic dictStr
end fn
local fn GetWord
dim as integer i, j, checkNum, numWords
checkNum = len( Edit$(9) )
edit$(10) = ""
long if checkNum < 3
edit$(11) = "Please enter at least three letters"
exit fn
end if
kill dynamic dictStr
gC = ""
fn FindDictionaryWords( edit$(9) )
numWords = fn UBound( dictStr )
long if numWords = 0
edit$(11) = "No words found."
xelse
edit$(11) = str$( numWords) + " words found"
end if
end fn = numWords
local fn ForwardReverse( whichWay as str15 )
dim as integer i, a, b
a = 0 : b = 0
appearance button 2
select case whichWay
case "reverse" : gDirection--
case "forward" : gDirection++
end select
if gDirection =< 1 then gDirection = 1
if gDirection => 16 then gDirection = 16
if gDirection = 1 then a = 1 : b = 499 : appearance button -2
if gDirection = 2 then a = 501 : b = 999
if gDirection = 3 then a = 1000 : b = 1499
if gDirection = 4 then a = 1500 : b = 1999
if gDirection = 5 then a = 2000 : b = 2499
if gDirection = 6 then a = 2500 : b = 2999
if gDirection = 7 then a = 3000 : b = 3499
if gDirection = 8 then a = 3500 : b = 3999
if gDirection = 9 then a = 4000 : b = 4499
if gDirection = 10 then a = 4500 : b = 4999
if gDirection = 11 then a = 5000 : b = 5499
if gDirection = 12 then a = 5500 : b = 5999
if gDirection = 13 then a = 6000 : b = 6499
if gDirection = 14 then a = 6500 : b = 6999
if gDirection = 15 then a = 7000 : b = 7499
if gDirection = 16 then a = 7500 : b = 8000
gC = ""
for i = a to b
gC += dictStr(i) + chr$(13)
next i
edit$( 10) = #gC
long if len(gC) = 500
gDirection = gDirection
appearance button -3
xelse
appearance button 3
end if
gC = ""
edit field 0
end fn
local fn HandleWords
dim as integer i, numWords
gDirection = 0
numWords = fn GetWord
long if numWords < 500
for i = 0 to numWords
gC += dictStr(i) + chr$(13)
next i
appearance button -2
appearance button -3
edit$( 10 ) = #gC
kill dynamic dictStr
gC = ""
xelse
for i = 0 to 500
gC += dictStr(i) + chr$(13)
next i
appearance button 3
edit$( 10, _maxInt, _maxInt ) = #gC
gC = ""
gDirection = 1
end if
end fn
local fn DoDialog
dim as long evnt, id
evnt = dialog(0)
id = dialog(evnt)
select case( evnt )
case _wndClose
select( id )
case 1 : gFBQuit = _zTrue
case 2 : window close 2
end select
case _btnClick
select( id )
case 1 : fn HandleWords
case 2 : fn ForwardReverse( "reverse" )
case 3 : fn ForwardReverse( "forward" )
end select
case _efReturn
select( id )
case 9 : fn HandleWords
end select
end select
end fn
local fn DoMenu
dim as long menuID, itemID
menuID = menu(_menuID)
itemID = menu(_itemID)
select case( menuID )
case _applemenu
select( itemID )
case 1 : fn AboutWindow
end select
case 1
select( itemID )
case 1 : fn HandleWords
end select
end select
menu
end fn
on dialog fn DoDialog
on menu fn DoMenu
fn BuildMenus
fn BuildWindow
do
handleevents
until gFBQuit
end