BEGIN External Class WindowTools; SideWindow Class OpenOrNewFileWindow( Hint, Path, NewFile, DefFileName ); Text Hint, Path, DefFileName; Boolean NewFile; BEGIN Ref(JPHPopupMenu) PathPopup; !The popup that shows the path; Ref(SelectionListWindow) DirList; !The current directory content; Ref(ScrollBar) TheScrollBar; !To scroll DirList; Ref(ScrollBox) UpBox, DownBox; Integer ScrollBoxWidth = 15, ScrollBoxHeight = 15; Ref(Button) Ok_Button, Cancel_Button; Ref(TextItemWindow) FileNameTI; !To specify a file name (newfile only); Text LineSelected, !The text of the line currently selected; DirName; !The current directory; Integer Selection, !A flag used to check if the final selection is made; Pending = 0, Cancelled = 1, Valid = 2, LineNbr; !The selection's line number; !++++++++++++++ Event handling ++++++++++++++; PROCEDURE InputInSubWindow( sw ); !When click in PathPopup; Ref(SubWindow) SW; IF SW == PathPopup THEN BEGIN IF PathPopup.DefSel = PathPopup.NumElems THEN ReadDir( "/" ) ELSE ReadDir( GetPathFromPopup ); END --- InputInSubWindow ---; PROCEDURE LineChoice( T, Nbr ); !When click in DirList; Text T; Integer Nbr; BEGIN LineSelected :- T; LineNbr := Nbr; END; PROCEDURE Handle_Return; BEGIN IF FileNameTI =/= None And then FileNameTI .Get =/= Notext THEN BEGIN Selection := Valid; SetAlarm( 0 ); !This sends an Evt so that we end the WaitForFile loop; END ELSE Browse; !This way, we "open" the selected line; END --- Handle_Return ---; PROCEDURE TreatEvt; !Used in WaitForFile; BEGIN Boolean PROCEDURE PtrInDL; !Checks if we clicked in DirList; BEGIN Integer DirX, DirY, X, Y; FindPointerPos( X, Y ); !We get the ptr position; DirList.FindAbsolutePos( DirX, DirY ); PtrInDL := DirX < X And X < DirX + DirList .Width !X is in DirList bounds; And DirY < Y And Y < DirY + DirList .Height; !Y is too; END --- PtrInDL ---; Ref(Button) Temp; Integer GInt; IF ButtonClicked( Temp ) THEN BEGIN !We pressed a button; IF Temp == Cancel_Button THEN Selection := Cancelled ELSE IF Temp == Ok_Button And NewFile And then FileNameTI .Get =/= Notext THEN !New file specified; Selection := Valid ELSE Browse;!Just as if double-clicked; END ELSE IF Clicked( GInt, GInt ) THEN BEGIN !We don't care about the pos here; IF PtrInDL THEN Browse; END; END --- TreatEvt ---; Text PROCEDURE WaitForFile; BEGIN SetSize( 400, 300 ); Show; ReadDir( Path ); WHILE Selection = Pending DO BEGIN WaitFor( alarmEvt + buttonEvt + clickEvt ); TreatEvt; END; IF Selection = Valid THEN !We return the correct text; WaitForFile :- GetPathFromPopup & "/" &( IF NewFile THEN FileNameTI.Get ELSE LineSelected ) ELSE WaitForFile :- Notext; !Cancel button hit, return notext; END --- WaitForFile ---; !++++++++++++++++ Browsing folders ++++++++++++++++; PROCEDURE Browse; !Dispatches the necessary actions when a line is selected; IF LineNbr > 2 THEN BEGIN IF Not DirList.Gray( LineNbr ) THEN BEGIN IF IsDir( LineSelected ) THEN ReadDir( DirName &( IF DirName <> "/" THEN "/" ELSE Notext ) & LineSelected .Sub( 1, LineSelected.Length-1 ) ) ELSE Selection := Valid; END; END ELSE IF LineNbr = 2 THEN ReadDir( PreviousDir( DirName ) ) ELSE ReadDir( DirName ); !A refresh; !+++++++++ Utilities +++++++++; Text PROCEDURE PreviousDir( t ); !Returns the text corresponding to ../ in UNIX; Text t; BEGIN Text Temp; Temp :- Scanto( t, '/' ); WHILE Not Rest( t ) = scanto( Rest( t ), '/' ) DO Temp :- Temp & "/" & Scanto( t, '/' ); IF Temp == Notext THEN PreviousDir :- "/" ELSE PreviousDir :- Temp; END --- PreviousDir ---; Boolean PROCEDURE IsDir( t ); !Returns true if the last char is '/'; Text t; BEGIN T.SetPos( T.Length ); IsDir := T.GetChar = '/'; END --- IsDir ---; Text PROCEDURE InvertPath( TextToInvert ); !Ex: "/a/b/c" -> "/c/b/a"; Text TextToInvert; BEGIN IF TextToInvert == Notext THEN InvertPath :- Notext ELSE BEGIN Text Temp; Temp :- ScanTo( TextToInvert, '/' ); InvertPath :- InvertPath( Rest( TextToInvert ) ) & "/" & Temp; END; END --- InvertPath ---; Text PROCEDURE GetPathFromPopup; !Gets the current working directory; INSPECT PathPopup DO BEGIN Integer i; Text NewPath; For i := DefSel Step 1 Until NumElems-1 DO NewPath :- "/" & Etiq( i ) & NewPath; GetPathFromPopup :- NewPath; END --- GetPathFromPopup ---; !+++++++++++++++ Screen printing +++++++++++++++; Boolean PROCEDURE ReadDir( path ); !Reads Path content and update DirList; Text path; BEGIN Ref(Table) Entries; Ref(Directory) Dir; Integer NbEntries, i; Text T, TempPathForPopup; Dir :- New Directory( path ); entries :- New table( 50 ); IF Dir.Open THEN BEGIN DirList.MakeEmpty; WHILE Dir.Nextentry DO BEGIN nbentries := nbentries + 1; entries.insert( New DirEntry( Dir.EntryName, Dir .EntryIsDir ) ); END; entries.sort; i := 0; For i := i + 1 WHILE i <= nbentries DO BEGIN t :- entries.get( i ) Qua direntry.filename; IF entries.get( i ) Qua direntry.isdir THEN t :- t & "/" ELSE IF NewFile THEN DirList.GrayLine( i ); DirList.SysPutLine( t ); END; !SysPutLine does not refresh the window; DirList.Refresh; Dir.Close; DirName :- Dir.Directory_name; PathPopup.SetMenu( InvertPath( DirName ) & "** ROOT **", "" ); ReadDir := True; END ELSE ReadDir := False; END --- ReadDir ---; PROCEDURE Refresh; BEGIN Head_Window.SetWidth( Width-SubWindowSpacing ); DirList.SetSize( Width-OK_Button.Width-ScrollBoxWidth-5* SubWindowSpacing, Height-PathPopup.Height-( IF FileNameTI =/= None THEN FileNameTI.Height ELSE 0 )-Head_Window.Height-6*SubWindowSpacing ) .PlaceLeftBelow( PathPopup ); PathPopup.PlaceAt(( DirList.Width-PathPopup .width )//2 + sw_gap, Head_Window.Height + 2*SubWindowSpacing ); UpBox.PlaceRightOf( DirList ).SetSize( ScrollBoxWidth, ScrollBoxHeight ); TheScrollBar.PlaceBelow( UpBox ).SetSize( ScrollBoxWidth, DirList .Height-2*( ScrollBoxHeight )-3*SubWindowSpacing + 1 ); DownBox.SetSize( ScrollBoxWidth, ScrollBoxHeight ) .PlaceBelow( TheScrollBar ); Ok_Button.PlaceRightOf( UpBox ); Cancel_Button.PlaceBelow( Ok_Button ); IF FileNameTI =/= None THEN FileNameTI.PlaceWithCenterIn( SubWindowSpacing + DirList .Width//2, DirList.Max_Y + SubWindowSpacing + FileNameTI .Height//2 ); END --- Refresh ---; !++++++++++++++ Initialization ++++++++++++++; !Button_Sensitize; !Key_Sensitize; SetBackGround( "gray55" ); SetHeading( Hint ); SetSize(400, 300); Ok_Button :- MakeButton( "Ok" ); Cancel_Button :- MakeButton( "Cancel" ); MakeButtonsSameWidth; PathPopup :- JPHMakePopupMenu( "/Invalid path", "" ) .Show; DirList :- New SelectionListWindow( This XWindow ) .Show; DirList.AllowChoice; TheScrollBar :- New ScrollBar( This XWindow, DirList ) .PlaceRightOf( DirList ) .Show; UpBox :- New ScrollBox( This XWindow, True, DirList ) .Show; DownBox :- New ScrollBox( This XWindow, False, DirList ) .Show; IF NewFile THEN FileNameTI :- MakeTextItem( "", 30 ).Put( DefFileName ); Refresh; END --- OpenOrNewFileWindow ---; INSPECT New FirstWindow( "Main" ) DO BEGIN Integer i; Text PROCEDURE GetFileName( Hint, Path ); Text Hint, Path; BEGIN Ref(OpenOrNewFileWindow) Temp; Temp :- New OpenOrNewFileWindow( Hint, This XWindow, Hint, Path, False, Notext ); GetFileName :- Temp.WaitForFile; Temp.Destroy; END; Text PROCEDURE GetNewFileName( Hint, Path, DefName ); Text Hint, Path, DefName; BEGIN Ref(OpenOrNewFileWindow) Temp; Temp :- New OpenOrNewFileWindow( Hint, This XWindow, Hint, Path, True, DefName ); GetNewFileName :- Temp.WaitForFile; Temp.Destroy; END; Text FN; OutLIne( Getfile("") ); FN :- GetFileName( "Open a file...", "" ); while FN <> Notext do begin OutLIne( "Open:" & FN & ":" ); FN :- GetFileName( "Open a file...", "" ); end; OutLIne( "Save:" & GetNewFileName( "Saving as...", "", "Untitled" ) & ":" ); END; END; % xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx % 0.933 sec cpu Simpp v1.3, tokenizer v2.7 % xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx