/* Copyright 1990-1992 Laboratoire de Recherche en Informatique (LRI)Permission to use, copy, and modify this software and its documentationfor your own purposes is hereby granted without fee, provided thatthe above copyright notice appear in all copies and that both thatcopyright notice and this permission notice appear in supportingdocumentation, and use acknowledge that the software was developedby Laboratoire de Recherche en Informatique, Universite de Paris-Sud,Orsay, France. LRI makes no representations about the suitability ofthis software for any purpose.  It is provided "as is" without expressor implied warranty.This software or modified versions of this software cannot bedistributed in source or binary form, nor included into productswithout prior written permission of the author.LRI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALLIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL LRIBE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGESWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTIONOF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.Author:   ___    0  Thomas Baudel                 e-mail: thomas@lri.fr  /   \  /   LRI - Bat 490 /  __/ /    Universite de Paris-Sud       voice : +33 (1) 69 41 69 10/__   \/     91 405 ORSAY Cedex - FRANCE   fax   : +33 (1) 69 41 65 86*//* INCLUDE */# include <Types.h> 				/* Nearly always required */# include <QuickDraw.h> 			/* To access the qd globals */# include <ToolUtils.h> 			/* CursHandle and iBeamCursor */# include <Fonts.h> 				/* Only for InitFonts() trap */# include <Events.h>				/* GetNextEvent(), ... */# include <OSEvents.h># include <Files.h># include <Strings.h># include <String.h># include <memory.h>#include <Values.h># include <Packages.h># include <Printing.h># include <CursorCtl.h># include <Resources.h>	# include <windows.h>				/* GetNewWindow(), ... */# include <dialogs.h>				/* InitDialogs() and GetNewDialog() */# include <menus.h> 				/* EnableItem(), DisableItem() */# include <desk.h>					/* SystemTask(), SystemClick() */# include <textedit.h>				/* TENew() */# include <scrap.h> 				/* ZeroScrap() */# include <SegLoad.h>				/* UnloadSeg() */# include <OSUtils.h>				/* SysBeep */#include "main.h"#include "Gesture.h"# define	aboutMeCommand	1# define	NewCommand 	1# define	OpenCommand 	2# define	SaveCommand 	4# define	SaveAsCommand 	5# define SaveInCommand	6# define	ParamCommand 	8# define	PrintCommand 9# define	QuitCommand 	11  #define LgParPage 5/* FONCTIONS UTILITAIRES */ FENETRE		*Fenetres, *CurFenetre;THPrint		PrInfos;Boolean 		DoneFlag, ImpressionCur;int 				CurCursor;RgnHandle 	mouseRgn;SysEnvRec	Environnement; void escape() { ExitToShell(); }FENETRE *TrouveFenetre (FENETRE *Doc) {Ê	FENETRE *Tampon;	Tampon = Fenetres;	while(Tampon && (Tampon!=Doc)) Tampon=Tampon->Suivant;	CurFenetre=Tampon;	return Tampon;}/* classe principale */FENETRE :: FENETRE (Str255 Titre, int TypeDoc, Boolean sv, Boolean sh) : TypeFenetre(TypeDoc), Suivant(Fenetres), LeMenu (GetMenu(TypeDoc)), Change(0), LeFichier(0){				Rect LeRect; WindowPeek CurPort;		Fenetres = this; CurFenetre=this;		if(Environnement.hasColorQD) GetNewCWindow (TypeDoc, (Ptr) &Fen, (WindowPtr) -1); 		else GetNewWindow(TypeDoc, (Ptr) &Fen, (WindowPtr) -1); 		if(FrontWindow()) {				CurPort=(WindowPeek) FrontWindow();				LeRect=(**(CurPort->strucRgn)).rgnBBox;				if(LeRect.top>290) LeRect.top=0;				if(LeRect.left>480) LeRect.left=0;				MoveWindow((WindowPtr) &Fen, LeRect.left+20, LeRect.top+40, false);			}		SetPort((GrafPtr) &Fen);		SetWTitle((WindowPtr) &Fen, Titre); 				if(sv) {			SETRECT(&LeRect, Fen.port.portRect.right-15, -1, Fen.port.portRect.right+1, Fen.port.portRect.bottom-14);			ControlV = GetNewControl(TypeDoc, (WindowPtr) &Fen);			(**ControlV).contrlRect = LeRect;  			HiliteControl(ControlV, 0); ShowControl(ControlV);		} else ControlV= 0;				if(sh) {			SETRECT(&LeRect, -1, Fen.port.portRect.bottom-15, Fen.port.portRect.right-14, Fen.port.portRect.bottom+1);			ControlH = GetNewControl(TypeDoc, (WindowPtr) &Fen);			(**ControlH).contrlRect = LeRect;			HiliteControl(ControlH, 0); ShowControl(ControlH);		} else ControlH= 0;}FENETRE :: ~FENETRE () {		FENETRE* h;	if(this == Fenetres) Fenetres = Fenetres->Suivant; 	else {				for (h = Fenetres; h->Suivant != this; h = h->Suivant) ;				h->Suivant = h->Suivant->Suivant;	}	if (ControlH) DisposeControl(ControlH); 	if (ControlV) DisposeControl(ControlV);	CloseWindow((WindowPtr) this);	// if (LeFichier) FSClose(LeFichier); *** appdependant	if (LeMenu) {ÊDeleteMenu(TypeFenetre); DrawMenuBar(); }}int FENETRE :: Enregistre (int ) { Change=0; return 0; }void FENETRE :: SetFontInfo(short what, TextStyle T, Boolean redessin) {	RgnHandle r; Rect LeRect;	switch(what) {		case doFont : TextFont(T.tsFont); break;		case doFace : TextFace(T.tsFace); break;		case doSize : TextSize(T.tsSize); break;		/* ajouter  la couleur*** */		default : break;	}	if (redessin) { 		r=NewRgn();		if(ControlH || ControlV)			SETRECT(&LeRect, 0, 0, Fen.port.portRect.right-15, Fen.port.portRect.bottom-15);		else SETRECT(&LeRect, -MAXSHORT, -MAXSHORT, MAXSHORT, MAXSHORT);		RectRgn(r, &LeRect); SetClip(r);		Dessine(r);		if(ControlH || ControlV) {			SETRECT(&LeRect, -MAXSHORT, -MAXSHORT, MAXSHORT, MAXSHORT);			RectRgn(r, &LeRect); SetClip(r);		}		DisposeRgn(r);	}}void FENETRE :: Oisif (Boolean) { }void FENETRE :: MenuEdition (short) { Alerte("Fonction non implantŽe"); }int FENETRE :: Dessine (RgnHandle) {Êreturn 1; }void FENETRE :: Update (RgnHandle r){	Rect LeRect; RgnHandle r2, r3;	if (ControlV) {	SETRECT(&LeRect, Fen.port.portRect.right-15, -1, Fen.port.portRect.right+1, Fen.port.portRect.bottom-14);	(**ControlV).contrlRect = LeRect;  	}	if (ControlH) {	SETRECT(&LeRect, -1, Fen.port.portRect.bottom-15, Fen.port.portRect.right-14, Fen.port.portRect.bottom+1);	(**ControlH).contrlRect = LeRect;	}	if(ControlH || ControlV) {			SETRECT(&LeRect, 0, 0, Fen.port.portRect.right-15, Fen.port.portRect.bottom-15);			r2=NewRgn(); r3=NewRgn(); RectRgn(r2, &LeRect);			SectRgn(r, r2, r3); SetClip(r3);			Dessine(r3);			SETRECT(&LeRect, -MAXSHORT, -MAXSHORT, MAXSHORT, MAXSHORT);			RectRgn(r2, &LeRect); SetClip(r2);			DisposeRgn(r2); DisposeRgn(r3);	} else {			SetClip(r);			Dessine(r);			SETRECT(&LeRect, -MAXSHORT, -MAXSHORT, MAXSHORT, MAXSHORT);			r2=NewRgn(); RectRgn(r2, &LeRect); SetClip(r2);			DisposeRgn(r2);	}	DrawControls((WindowPtr) &Fen);	if(ControlH || ControlV) DrawGrowIcon((WindowPtr) &Fen);}void FENETRE :: ControlClique (EventRecord*, ControlHandle, int) { }void FENETRE :: Active (int) { }void FENETRE :: Touche (EventRecord*) {Ê}void FENETRE :: Clique (EventRecord*) { }void FENETRE :: Menu (int) { }void FENETRE :: Scrolle (short, short) { } void FENETRE :: Imprime (THPrint Infos) { 		RgnHandle r=NewRgn(); 		TPrStatus Statut;		int j=1, k, l=0, m; 		TPPrPort LePort=PrOpenDoc(Infos, nil, nil); 		int i = (*Infos)->prJob.iFstPage;		if (i <= 0) i = 1;		ImpressionCur=true;		if  (ControlV) Scrolle(0, -GetCtlValue(ControlV));		while (! PrError() && j < i && (! ControlV || l < GetCtlMax(ControlV)) ) {				SetPort((GrafPtr) LePort);  				TextFont (Fen.port.txFont); TextFace(Fen.port.txFace); 				TextMode (Fen.port.txMode); TextSize(Fen.port.txSize);				RectRgn (r, &(LePort->gPort.portRect));				SetClip(r);				 m=Dessine(r); l+=m;				if (ControlV) { SetPort((GrafPtr) &Fen); Scrolle(0, m); SetCtlValue(ControlV, l); }				j++;			} 		i=(*Infos)->prJob.iLstPage; // erreur : si on a moins de pages a imprimer (pas de scrollbar)		while(! PrError() && j <= i && (! ControlV || l<GetCtlMax(ControlV)) ) {				for (k=0; k< (*Infos)->prJob.iCopies; k++) {					PrOpenPage(LePort, nil);					if ( PrError()==noErr ) {							SetPort((GrafPtr) LePort);  							TextFont(Fen.port.txFont); TextFace(Fen.port.txFace); 							TextMode(Fen.port.txMode); TextSize(Fen.port.txSize);							RectRgn (r, &(LePort->gPort.portRect));							SetClip(r);							m=Dessine(r);  l+=m;							if (ControlV) { SetPort((GrafPtr) &Fen);  Scrolle(0, m); SetCtlValue(ControlV, l); }							PrClosePage(LePort);					} else break;				}				if (!ControlV) break;				j++;			}		PrCloseDoc(LePort);		if ( (*Infos)->prJob.bJDocLoop==bSpoolLoop && PrError()==noErr ) 					PrPicFile(Infos, nil, nil, nil, &Statut);		if ( PrError() ) Alerte ("Erreur ˆ l'impression ");		ImpressionCur=false;		SetPort( (GrafPtr) this); 		RectRgn(r, &(Fen.port.portRect));		Update(r);		DisposeRgn(r); }/* BOUCLE PRINCIPALE */void GereOisif () { 	FENETRE *Doc; FENETRE *Doc2; GrafPtr OldPort;	SystemTask(); GetPort(&OldPort);	Doc2 = TrouveFenetre((FENETRE*) FrontWindow()) ;	for(Doc = Fenetres; Doc != NULL; Doc = Doc->Suivant) {			SetPort((GrafPtr) Doc); CurFenetre=Doc;			if( Doc == Doc2 ) Doc->Oisif(true); else Doc->Oisif(false);	}	SetPort(OldPort);}void doCommand(long mResult) {	int 				theMenu, theItem;	Str255			ch;	TextStyle		TStyle;	SFTypeList tl; 	FENETRE*		Doc = TrouveFenetre((FENETRE*) FrontWindow());	theItem = (int) LOWORD(mResult); theMenu = (int) HIWORD(mResult); 	switch (theMenu) {		case appleID:			if (theItem == aboutMeCommand) { AProposDialogue(); } 			else { GetItem(GetMenu(appleID), theItem, ch); OpenDeskAcc(ch); }			break;		case fileID:			switch (theItem) {				case NewCommand : 						GetIndString(ch, 130, 1);						new FENETRE_SET (ch, 0); break; // *** appdependant 				case OpenCommand : 						tl[0] = 'GEST'; tl[1]='    '; tl[2]='    '; tl[3]='    ';						ch[0]=0; 						theItem = GetDocument (ch, (SFTypeList*) &tl, 1);						if(theItem) new FENETRE_SET (ch, theItem); break; // *** appdependant 				case SaveCommand : if (Doc) if(! Doc->Change) break;				case SaveAsCommand : 				case SaveInCommand : if (Doc) { 									SetPort((GrafPtr) Doc);									Doc->Enregistre (theItem - SaveCommand); 									}							break;				case ParamCommand : 	PrOpen (); 													PrintDefault(PrInfos); PrStlDialog(PrInfos);													PrClose(); break;				case PrintCommand :  if (Doc) { SetPort((GrafPtr) Doc);												PrOpen(); 												if(PrValidate(PrInfos)) { PrStlDialog(PrInfos); }												if(PrJobDialog(PrInfos))  Doc->Imprime(PrInfos); 												PrClose();												}  break;				case QuitCommand: theItem=1;						for(Doc = Fenetres; Doc != NULL && theItem; Doc = Doc->Suivant) {								switch(Confirme3("Save Changes ?")) { // **** take window Title										case 1 : Doc->Enregistre (0);  										case 2 : delete Doc; break;										case 3 : theItem=false; break;								}							}						if(theItem) DoneFlag = true; break;				default: break;			} 			break;		case editID:			if (SystemEdit( theItem-1) && (theItem <= clearCommand)) { break; }			if (Doc) { SetPort((GrafPtr) Doc);  					if (theItem==1 && Doc->Refait==true) { theItem=2; Doc->Refait=false; }					else Doc->Refait=true;					Doc->MenuEdition(theItem);  				}			break;		case MFontID : GetItem(GetMenu(MFontID), theItem, ch);								GetFNum(ch, &TStyle.tsFont) ; theItem=doFont; 		case MStyleID :						if (theMenu==MStyleID) {							if (theItem>9) { 									GetItem(GetMenu(MStyleID), theItem, ch);									TStyle.tsSize = ch[1]-'0';									if(ch[2]!=' ') TStyle.tsSize = 10*TStyle.tsSize + ch[2]-'0'; 									theItem = doSize; 							} 						else { TStyle.tsFace= theItem-1; theItem=doFace; }						}				if (Doc) { SetPort((GrafPtr) Doc); Doc->SetFontInfo(theItem, TStyle, true); } break;		default: if (Doc) { SetPort((GrafPtr) Doc); Doc->Menu(theItem); } break; // *** appdependant 	} HiliteMenu(0); return;}resultat TrouveEvnmt(int masque, EventRecord* Evt, Boolean w) {  unsigned long i;  if(w) i=2000; else i=0;  GereOisif(); 	 if ( GetNextEvent(masque, Evt) ) return(oui);  // if ( WaitNextEvent(masque, Evt, i, mouseRgn) ) return(oui);  /* faire every event et comparer les masques pour retourner non */  else return(rien);}void Scroller(FENETRE *Doc, ControlHandle LeControle, Boolean v, int i, int Endroit){	Point LePoint; int vf;	while ( StillDown() ) 	{		GetMouse( &LePoint );		if  (TestControl(LeControle, LePoint) == Endroit ) 				{					HiliteControl(LeControle, Endroit); 					vf = GetCtlValue(LeControle) + i;					if (vf <= 0) {Êvf=0; }					else {  if (vf > GetCtlMax(LeControle) ) vf=GetCtlMax(LeControle); }					if( vf  !=  GetCtlValue(LeControle) ) {						if (v) Doc->Scrolle(0, vf - GetCtlValue(LeControle));						else Doc->Scrolle(vf - GetCtlValue(LeControle), 0);						SetCtlValue(LeControle, vf);					}				}	}	HiliteControl(LeControle, 0);	}void GereEvnmt(EventRecord Evt) {				WindowPtr whichWindow; FENETRE *Doc; long i; Rect r, r2; GrafPtr OldPort; int j;		ControlHandle LeControle; 				switch (Evt.what) {			case mouseDown:				switch (j=FindWindow(Evt.where, &whichWindow)) {					case inMenuBar: doCommand(MenuSelect(Evt.where)); break;					case inSysWindow: SystemClick(&Evt, whichWindow); break;					case inContent:						if ( FrontWindow() != whichWindow ) { SelectWindow(whichWindow); }						else if (Doc = TrouveFenetre( (FENETRE*) whichWindow)) { 							SetPort((GrafPtr) Doc); 							GlobalToLocal(&Evt.where);							if (j = FindControl(Evt.where, (WindowPtr) Doc, &LeControle)) {								if ( LeControle == Doc->ControlH) {										switch(j) {											case inUpButton: Scroller(Doc, LeControle , false, -1, inUpButton); break;											case inDownButton: Scroller(Doc, LeControle , false, 1, inDownButton); break;											case inPageUp: Scroller(Doc, LeControle , false, -LgParPage, inPageUp); break;											case inPageDown: Scroller(Doc, LeControle , false, LgParPage, inPageDown); break;											default: j=GetCtlValue(LeControle);													if (TrackControl(LeControle, Evt.where, NULL)==inThumb) 													Doc->Scrolle(GetCtlValue(LeControle)-j, 0); 										}								} else if (LeControle == Doc->ControlV) {									switch(j) {											case inUpButton: Scroller(Doc, LeControle , true, -1, inUpButton); break;											case inDownButton: Scroller(Doc, LeControle , true, 1, inDownButton); break;											case inPageUp: Scroller(Doc, LeControle , true, -LgParPage, inPageUp); break;											case inPageDown: Scroller(Doc, LeControle , true, LgParPage, inPageDown); break;											default: j=GetCtlValue(LeControle);														if (TrackControl(LeControle, Evt.where, NULL)==inThumb) 														Doc->Scrolle(0, GetCtlValue(LeControle)-j); 										}								} else {ÊDoc->ControlClique(&Evt, LeControle, j); }							} else Doc->Clique(&Evt); 						}							break;					case inDrag: DragWindow(whichWindow, Evt.where, &qd.screenBits.bounds); break;					case inGrow: if( i=GrowWindow(whichWindow, Evt.where, &qd.screenBits.bounds)) {								if(((WindowPeek) whichWindow)->controlList) { 									SETRECT(&r, whichWindow->portRect.right-16, whichWindow->portRect.top, 														whichWindow->portRect.right, whichWindow->portRect.bottom);									SETRECT(&r2, whichWindow->portRect.left, whichWindow->portRect.bottom-16, 														whichWindow->portRect.right, whichWindow->portRect.bottom);								}								SizeWindow(whichWindow, (short) LOWORD(i), (short) HIWORD(i), true); 								if(((WindowPeek) whichWindow)->controlList) { 									GetPort(&OldPort); SetPort(whichWindow);									InvalRect(&r); InvalRect(&r2); 									SETRECT(&r, whichWindow->portRect.right-16, whichWindow->portRect.top, 														whichWindow->portRect.right, whichWindow->portRect.bottom);									InvalRect(&r); 									SETRECT(&r, whichWindow->portRect.left, whichWindow->portRect.bottom-16, 														whichWindow->portRect.right, whichWindow->portRect.bottom);									InvalRect(&r);									SetPort(OldPort);									}								}							break;					case inGoAway : if (Doc=TrouveFenetre( (FENETRE*) whichWindow)) { 							if (TrackGoAway(whichWindow, Evt.where)) {								if(Doc->Change) {									SetPort((GrafPtr) Doc);									switch(Confirme3("Voulez-vous enregistrer les modifications ?")) {  /***/										case 1 : if(! Doc->Enregistre(0)) break;										case 2 : delete Doc; break;										default : break;									} }								else delete Doc; 							} }Êbreak;					case inZoomIn : 					case inZoomOut : 							if (TrackBox (whichWindow, Evt.where, j)) {								GetPort(&OldPort); SetPort(whichWindow);								EraseRect(&(whichWindow->portRect));								ZoomWindow(whichWindow, j, false);								SetPort(OldPort);							}							break;					default: break;					} /*endsw FindWindow*/				break;			case keyDown:			case autoKey:					if (Evt.modifiers & cmdKey) {						doCommand(MenuKey((char) (Evt.message & charCodeMask)));					} else {						if (Doc=TrouveFenetre( (FENETRE*) FrontWindow())) { 							SetPort((GrafPtr) Doc); 							Doc->Touche(&Evt); 						} else SysBeep(5);					}				break;			case activateEvt: if (Doc = TrouveFenetre((FENETRE*) Evt.message)) {					GetPort(&OldPort); SetPort((GrafPtr) Evt.message);					Doc->Active(Evt.modifiers & activeFlag); 					SetPort(OldPort);					}				break;			case updateEvt:				if (Doc = TrouveFenetre((FENETRE*) Evt.message)) {					SetPort((GrafPtr) Doc);					BeginUpdate((WindowPtr) Evt.message);						Doc->Update((RgnHandle) Doc->Fen.port.visRgn); 					EndUpdate((WindowPtr) Evt.message);				} break;			default: break;		}}Ê/* GereEvnmt *//*  INITIALISATION */#pragma segment Initialisationvoid InitProgramme() { // *** app dependent} void initialise() {	 	Handle LaBarre; 	short i, j, Test; short LeFichierS; 	AppFile TheFile; FENETRE* Tamp;		UnloadSeg(_DataInit);	MaxApplZone(); MoreMasters(); MoreMasters(); MoreMasters();	FlushEvents(everyEvent, 0); InitGraf(&qd.thePort); InitFonts();	InitWindows(); InitMenus(); TEInit(); InitDialogs( NULL); InitCursor(); InitCursorCtl(NULL);	LaBarre=GetNewMBar(1); AddResMenu(GetMenu(appleID),'DRVR');	SetMenuBar(LaBarre); DrawMenuBar();	Test=SysEnvirons(1, &Environnement);	Fenetres = NULL; DoneFlag = 0;  ImpressionCur=false; 	mouseRgn=NewRgn(); CurCursor=ARROW_CURSOR;	LoadScrap(); 	PrInfos=(THPrint) NewHandle(sizeof(TPrint)); 	CouldAlert(130);		InitProgramme();	CountAppFiles(&i, &j);	while(j > 0) {			GetAppFiles(j, &TheFile); 			Test=SetVol(NULL, TheFile.vRefNum);			LeFichierS=OpenResFile (TheFile.fName); // *** appdependant			if(LeFichierS)				new FENETRE_SET (TheFile.fName, LeFichierS); // *** appdependant 			ClrAppFiles(j--);		}	if (i==appPrint) {		PrOpen(); PrintDefault(PrInfos);		if(PrStlDialog(PrInfos)) {			if(PrJobDialog(PrInfos)) { 			while(Fenetres) {					CurFenetre=Fenetres;					SetPort((GrafPtr) Fenetres);					Fenetres->Imprime(PrInfos);					Tamp=Fenetres; Fenetres=Fenetres->Suivant;					delete Tamp;				}			}		}		PrClose(); 		DoneFlag=true;	}}#pragma segment Mainint main() {	EventRecord Evt;	initialise(); UnloadSeg(initialise);	do {		if(TrouveEvnmt(everyEvent, &Evt, true)==oui) GereEvnmt(Evt);	} while(!DoneFlag);	UnloadScrap();	return(0);}
