{ Copyright 1990-1993 Apple Computer, Inc. All Rights Reserved } { 26-Jan-93 SS -- switched to newer call GetCtlValueByID} UNIT FindFileDA; INTERFACE USES Types, GSOS, QuickDraw, IntMath, Events, Controls, Windows, Menus, Desk, LineEdit, ProDOS, Lists, Resources, Memory, Locator, MiscTool, Loader; {$Z+} {So 'C' routines know about these names} const MyDATitle = ' Find File 1.1 '; MaxFilesToFind = 200; { matches MaxEntries constant in ProcessLevel.asm } type MyListRec = Record MemString:ptr; MemFlag:Integer; MemFullName:Handle; memType:Integer; memAux:Longint; memEOF:Longint; end; MyListHand = ^MyListPtr; MyListPtr = ^MyListarray; MyListArray= Array[0..100] of MyListRec; Str255Ptr=^str255; Str255Hndl=^Str255Ptr; convtype = packed array [1..31] of char; convptr = ^convtype; ConvHndl = ^ConvPtr; VAR IdleWind : GrafPortPtr; { do not remove } initType, { do not remove } Stk_Size, { do not remove } quitflag, { do not remove } menuID, { do not remove } itemID, { do not remove } actionCode : Integer; { do not remove } eventP : EventRecordPtr; { do not remove } InvisibleFlag: boolean; { true if invisible files should be found } tempRect :Rect; MyList : MyListHand; messageStr :str255; tempString : str255; { used by ProcessLevel.asm } currentDirPath:str255; { used by ProcessLevel.asm } MyDirEntry : DirEntryRec; MyOpenRec : OpenRec; MyCLose : FileIORec; MyListCnt : Integer; ListCtrl : CtlRecHndl; MyID : Integer; MatchType : Integer; MatchStr : str32; CurrentVol: str32; VolPopUp,tempBar : MenuBarRecHndl; StackHandle : Longint; StackLevel : Integer; EntryCount : Integer; PascalStack: Integer; Running:Integer; { Flag that tells us if we are currently running } Stopping : Integer; {Flag that tells us that we should stop and why} IdleCount : Integer; AsmToolErr : Integer; PathListHidden : Boolean; tempNamePtr : Record stat:integer; length:integer; theName:packed array [1..40] of char; end; screenMode : Integer; PROCEDURE ReallyOpen; { do not remove } PROCEDURE ReallyInit; { do not remove } PROCEDURE ReallyClose; { do not remove } PROCEDURE ReallyAction; { do not remove } Procedure SetMessage(theString:str255); IMPLEMENTATION {$Z-} { hide the rest } { place variables & constants here that need to be known between calls } TYPE integerPtr = ^integer; MyTaskRec= RECORD wmWhat : Integer; wmMessage : Longint; wmWhen : Longint; wmWhere : Point; wmModifiers : Integer; wmTaskData : Longint; { TaskMaster return value. } wmTaskMask : Longint; { TaskMaster feature mask. } wmLastClickTick : Longint; wmClickCount : Integer; wmTaskData2 : Longint; wmTaskData3 : Longint; wmTaskData4 : Longint; wmLastClickPt : Point; wmBuffer : array[0..4] of Integer; END; VAR windParams : ParamList; emptyString : String[1]; titleStr: String[32]; AppResFork : Integer; theDATask : MyTaskRec; PROCEDURE BeginDA; EXTERNAL; PROCEDURE AddVolumeMenu; EXTERNAL; PROCEDURE CallNotifyProc; EXTERNAL; PROCEDURE CallDelNotifyProc; EXTERNAL; Function MakeCurPath:Boolean; EXTERNAL; PROCEDURE TestSetKT; EXTERNAL; PROCEDURE ServiceDiskSwitch; EXTERNAL; PROCEDURE PollDevices; External; PROCEDURE GetUpTextFromLE(theLEHandle:LERecHndl; var theStr:str32); External; PROCEDURE MyMemberDraw; External; PROCEDURE SetAboutMessage; External; Function ffRequestProc(code: integer; inP, outP: univ longint): integer; External; Procedure InstallMyRequestProc; External; Procedure CreatePathList(thePath:ptr); External; procedure MakeSureExtraToolsAreHere; external; Procedure Debug; INLINE $0000 ; Procedure DebugStr(theStr:str255); INLINE $A2,$FF09,$22,$E10000; { Function GetCtlValueByID(theWindow:WindowPtr; theID:longint) : integer; INLINE $A2,$3D10,$22,$E10000; } Procedure SetControls(running:Boolean); var RunButton, StopButton, LineEditCtl, DiskPopUp, MatchPopUp: CtlRecHndl; begin RunButton := GetCtlHandleFromID(IdleWind,1001); StopButton := GetCtlHandleFromID(IdleWind,1002); LineEditCtl := GetCtlHandleFromID(IdleWind,$3f0); DiskPopUp := GetCtlHandleFromID(IdleWind,1); MatchPopUp := GetCtlHandleFromID(IdleWind,$3EE); If Running then begin HideControl(RunButton); ShowControl(StopButton); HiliteControl($FF,LineEditCtl); HiliteControl($FF,DiskPopUp); HiliteControl($FF,MatchPopUp); end else begin HideControl(StopButton); ShowControl(RunButton); HiliteControl(0,LineEditCtl); HiliteControl(0,DiskPopUp); HiliteControl(0,MatchPopUp); end; end; { ------------------------------------------------------------------------------------} { This procedure is called when the desk accessory is selected from the } { Apple menu. It will only be called once. Any re-selection of the DA's } { menu item will be filtered out before reaching this routine. } PROCEDURE ReallyOpen; VAR oldRgn, tmpRgn : RegionHndl; myPoint : Ptr; temp,errtemp:Integer; fileOpen,Abort:Boolean; prefsParms : SysPrefsRecGS; oldPrefs : Integer; BEGIN emptyString := ''; MyID:=MMStartup; ResourceStartup(MyID); fileOpen:=false; PathListHidden:=true; Abort:=false; { save current SysPrefs and set them up to automatically display mount dialog } prefsParms.pCount := 1; GetSysPrefsGS(prefsParms); oldPrefs := prefsParms.preferences; prefsParms.preferences := $8000; { show 'dem dialogs! } SetSysPrefsGS(prefsParms); {GAB} Repeat temp := OpenResourceFile(1,NIL,GSString255Ptr(LGetPathname2(MyID,1))); If _ToolErr=0 then FileOpen:=true else begin If _ToolErr=volNotFound then Abort := true {User must have selected "Cancel" in volume mount dialog} else Begin errTemp:=TLMountVolume(30,30,'Error occured while opening', 'Find File', 'Try Again', 'Cancel'); If errTemp=2 then Abort:=true; end end; until fileOpen or Abort; { reset SysPrefs to original value } prefsParms.preferences := oldPrefs; SetSysPrefsGS(prefsParms); {GAB} If Abort then begin idleWind:=NIL; ResourceShutDown; exit(ReallyOpen); end; MakeSureExtraToolsAreHere; titleStr:=MyDATitle; MessageStr:=''; if BAnd(GetMasterSCB,$0080) = 0 then { determine what screen mode we're in } screenMode := 320 else screenMode := 640; IdleWind := NewWindow2(@titleStr,0,NIL,NIL,$0002,ref(screenMode),$800E); SetControls(false); if _toolErr <> 0 THEN SysFailMgr(_toolErr,emptyString); SetSysWindow(IdleWind); quitflag := 0; { set to 1 by action routine if its time to quit } ListCtrl := GetCtlHandleFromID(IdleWind,longint(1009 + screenMode)); MyList := MyListHand(NewHandle(20*MaxFilesToFind,MyID,$8000,NIL)); AddVolumeMenu; CallNotifyProc; MyListCnt := 0; MatchType := 1; END; {ReallyOpen} { ------------------------------------------------------------------------------------} { This procedure is called when DeskStartUp or DeskShutDown is called } { It is normally not used but is used here so that the header for the } { desk accessory can be built from Pascal } PROCEDURE ReallyInit; TYPE DAHeader = RECORD openPtr : LongInt; { pointer to open routine (do not change) } closePtr : LongInt; { pointer to close routine (do not change) } actionPtr : LongInt; { pointer to action routine (do not change) } initPtr : LongInt; { pointer to init routine (do not change) } period : Integer; { How often the DA is to get a run call - set in make file } eventMask : Integer; { Discribes what events DA responds to - set in make file } menuLine : packed ARRAY [0..20] of char; END; DAHeaderPtr = ^DAHEADER; VAR customHeader : DAHeaderPtr; BEGIN IF initType <> 0 THEN BEGIN { DeskStartUp call being made } customHeader := DAHeaderPtr(@BeginDA); { change the following if you want more or less stack } Stk_Size := 2048; { live with applications } END ELSE BEGIN { DeskShutDown call being made - this is not close desk accessory} InstallMyRequestProc; END; END; { ------------------------------------------------------------------------------------} { This procedure is called when the desk accessory is about to close. } PROCEDURE ReallyClose; BEGIN DisposeAll(MyID+$0700); DisposeAll(MyID+$0600); DisposeAll(MyID+$0900); DisposeAll(MyID+$0300); { added 9-Apr-92 DAL -- get rid of list items! } DisposeHandle(Handle(MyList)); StackHandle := 0; Running := 0; myListCnt:=0; CallDelNotifyProc; { remove the disk switch routine from GS/OS notif. queue } CloseWindow(IdleWind); ResourceShutDown; Stopping := 1; END; { ReallyClose } { ------------------------------------------------------------------------------------} { This procedure handles any events or periodic run requests which are passed } { to the desk accessory. } Procedure ShowMessage; var PathList: CtlRecHndl; tempPort: GrafPortPtr; tempRgn: RegionHndl; myRect: Rect; begin PathList := GetCtlHandleFromID(IdleWind,1015 + screenMode); PathListHidden := true; { Set the clip rect here to avoid mucking up the list above?? } tempPort := GetPort; SetPort(IdleWind); tempRgn := NewRgn; GetClip(tempRgn); SetRect(myRect,0,100,1000,1000); { don't mess up anything above top of list } ClipRect(myRect); HideControl(PathList); SetClip(tempRgn); DisposeRgn(tempRgn); SetPort(tempPort); end; Procedure ShowPathList; var PathList:CtlRecHndl; begin PathList:=getCtlHandleFromID(IdleWind,1015 + screenMode); ShowControl(PathList); PathListHidden:=false; end; procedure UpdateMessageBox; var tempPort: GrafPortPtr; begin if PathListHidden then begin tempPort := GetPort; SetPort(IdleWind); SetRect(tempRect,4,105,318,145); LETextBox2(ptr(ord4(@MessageStr)+1),length(MessageStr),tempRect,0); SetPort(tempPort); end; end; Procedure SetMessage(theString:str255); var savePort : GrafPortPtr; begin savePort := GetPort; SetPort(IdleWind); ShowMessage; MessageStr := theString; SetPort(savePort); UpdateMessageBox; end; { This routine should be called at the start of every search to dump the current list and all its contents, as well as called for shutdown... } Procedure DumpList; begin DisposeAll(MyID+$0700); myListCnt := 0; NewList2(NIL,1,ref(MyList),1,myListCnt,listCtrl); BeginUpdate(IdleWind); { make sure the old list disappears } DrawControls(IdleWind); EndUpdate(IdleWind); end; Function ProcessLevel(Flag:Integer):Integer; External; { This procedure should be called before any routine starts/ends to determine if the state of the buttons needs to be changed. } Procedure Idler; var i,j:Integer; MyLERecord:LERecHndl; RunButton:CtlRecHndl; StopButton:CtlRecHndl; theState:Byte; begin MyLERecord := LERecHndl(GetCtlTitle(GetCtlHandleFromID(IdleWind,1008))); RunButton := GetCtlHandleFromID(IdleWind,1001); StopButton := GetCtlHandleFromID(IdleWind,1002); If Running<>0 then begin idleCount:=0; end else begin IdleCount := IdleCount + 1; PollDevices; ServiceDiskSwitch; theState:=RunButton^^.ctlHilite; i := LEGetTextLen(MyLERecord); If (theState=noHilite) and (i=0) then HiliteControl(inactiveHilite,RunButton); If (theState=inactiveHilite) and (i<>0) then HiliteControl(noHilite,RunButton); end; end; Procedure StartSearch(doInvisibles: boolean); var i, j: Integer; MyLERecord: LERecHndl; begin { First set up MatchType and MatchStr } MyLERecord:=LERecHndl(GetCtlTitle(GetCtlHandleFromID(IdleWind,1008))); GetUpTextFromLE(MyLERecord,MatchStr); {Get the user inputed file choice..} If Length(MatchStr)=0 then Exit(StartSearch); SetControls(true); StackHandle := 0; stackLevel := 0; {*** changed to new call 26-Jan-93 SS} { i := GetCtlValue(GetCtlHandleFromID(IdleWind,1006)); } i := GetCtlValueByID(IdleWind,1006); {*** end 26-Jan-93} MatchType := i-1600; DumpList; SetMessage('Searching...'); { get the proper prefix to use... } If not MakeCurPath then ; { What is this?? --DAL } Stopping := 0; {Set the stopping flag to zero....} InvisibleFlag := doInvisibles; Running := processLevel(0); {Start the recursion} end; Procedure DisplayItem; const theLeftEdge=190; theTopEdge=62; var MyHand:Str255Hndl; theItem:Integer; tempPort:grafportPtr; begin tempport := GetPort; SetPort(IdleWind); theItem:=NextMember2(0,ListCtrl); {Get the member to display} If theItem=0 then begin SetABoutMessage; Exit(DisplayItem); end; MyHand:=Str255Hndl(MyList^^[theItem-1].MemFullName); CreatePathList(Ptr(MyHand^)); ShowPathList; SetPort(tempPort); end; Procedure Continue(Chunkiness: integer); var MyHand:Str255Hndl; theItem:Integer; tempPort:grafportPtr; tempLong:Longint; StartTick: longint; dummyEvent: EventRecord; begin if running<>0 then begin StartTick := GetTick; while ((GetTick-StartTick) < Chunkiness) and (Running<>0) and not EventAvail(mDownMask+keyDownMask+autoKeyMask,dummyEvent) do begin running := processlevel(0); end; end else begin if StackHandle<>0 then begin tempport := GetPort; SetPort(IdleWind); DisposeHandle(Handle(StackHandle)); tempLong:=Longint(GetCtlTitle(ListCtrl)); {Get the ctlData field} if (tempLong0); 1002: StopSearch; { 1003: ; } { 1004: ; } { 1005: ; } { 1006: ; } { Matches popup displayed... } { 1007: ; } { 1008: ; } 1009 + 320, 1009 + 640: DisplayItem; { 1010: ; } { 1011: ; } { 1012: ; } { 1013: ; } { 1014: ; } { 1015: ; } end; end; PROCEDURE ReallyAction; CONST XSpan = 145; YSpan = 168; VAR savePort : GrafPortPtr; newX, newY : integer; code :Integer; theRect : Rect; BEGIN theDATask.wmWhat:=EventP^.wmWhat; theDATask.wmMessage:=EventP^.wmMessage; theDATask.wmWhen:=EventP^.wmWhen; theDATask.wmWhere:=EventP^.wmWhere; theDATask.wmModifiers:=EventP^.wmModifiers; theDATask.wmTaskData:=0; theDATask.wmTaskMask:=$1FFFFF; CASE ActionCode of runAction: BEGIN { a periodic call is being made } savePort := GetPort; SetPort(IdleWind); LEIdle(LERecHndl(GetCtlTitle(GetCtlHandleFromID(IdleWind,$3F0)))); continue(15); {call the idle routine} Idler; SetPort(savePort); END; cursorAction: { like Run, but don't call Idler! } BEGIN savePort := GetPort; SetPort(IdleWind); continue(50); {call the idle routine} SetPort(savePort); END; eventAction: BEGIN { an event has been passed to the DA } CASE EventP^.what OF updateEvt: BEGIN BeginUpdate(IdleWind); DrawControls(IdleWind); PenNormal; UpdateMessageBox; EndUpdate(IdleWind); Idler; END; keyDownEvt, autoKeyEvt: Begin code:= band($00FF,theDATask.wmMessage); if (code=13) and (Running=0) then StartSearch(band(theDATask.wmModifiers,optionKey)<>0) else begin if (code=10) or (code=11) then theDATask.wmWhat := 0; { up/down arrows } if (running=0) and (code=27) {esc} then theDATask.wmMessage := 24; { Clear } if (code=46) { period } and (band(theDATask.wmModifiers,$0100)<>0) then theDATask.wmMessage := 27; { command-period --> esc } code:=TaskMasterDA($FFFF,@theDATask); if code = wInControl then HandleControl(theDATask.wmTaskData4,theDATask.wmModifiers); Idler; end; End; mouseDownEvt, mouseUpEvt, ActivateEvt: BEGIN code:=TaskMasterDA($FFFF,@theDATask); if code = wInControl then HandleControl(theDATask.wmTaskData4, theDATask.wmModifiers); Idler; END; END; { CASE } END; END; { CASE } END; END. { of Unit }