/***********************************************************************/ /* */ /* Objective Caml */ /* */ /* Damien Doligez, projet Para, INRIA Rocquencourt */ /* */ /* Copyright 1997 Institut National de Recherche en Informatique et */ /* en Automatique. All rights reserved. This file is distributed */ /* under the terms of the GNU Library General Public License. */ /* */ /***********************************************************************/ /* $Id$ */ #include "main.h" static unsigned long nuntitled = 0; static unsigned long count = 2; /* XXX prŽvoir le cas o on peut Žcrire le texte mais pas les ressources -> resrefnum peut tre -1 quand datarefnum est valide */ static void MakeUntitledTitle (Str255 result) { char buffer [15]; GetIndString (result, kMiscStrings, kUntitledIdx); if (nuntitled != 0){ if (result [0] > 240) result [0] = 240; sprintf (buffer, " %lu", count); Assert (strlen (buffer) < 15); strcpy ((char *) result + result [0] + 1, buffer); result [0] += strlen (buffer); ++ count; }else{ count = 2; } ++ nuntitled; } static void FreeUntitledTitle () { -- nuntitled; } /* Close the file associated with the window, saving it if needed. */ OSErr FileDoClose (WindowPtr w, ClosingOption close) { WStatusH st; WEHandle we; Str255 savingprompt, filename; short item; OSErr err; Assert (WinGetKind (w) == kWinDocument); WinUpdateStatus (w); st = WinGetStatus (w); Assert (st != NULL); we = WinGetWE (w); Assert (we != NULL); GetWTitle (w, filename); if ((*st)->menuflags.save){ GetIndString (savingprompt, kMiscStrings, kClosingIdx + close); ParamText (filename, savingprompt, NULL, NULL); InitCursor (); modalkeys = kKeysSaveDontCancel; item = Alert (kAlertSaveAsk, myModalFilterUPP); switch (item){ case 1: /* Yes */ err = FileDoSave (w, 0); if (err != noErr) return err; break; case 2: /* Cancel */ return userCanceledErr; case 3: /* No */ break; default: Assert (0); } }else{ if ((*st)->resrefnum != -1){ /* XXX sauver fenetre, selection, scrollbars */ } } if ((*st)->datarefnum == -1){ Assert ((*st)->resrefnum == -1); FreeUntitledTitle (); }else{ FSClose ((*st)->datarefnum); if ((*st)->resrefnum != -1) CloseResFile ((*st)->resrefnum); } return noErr; } /* Open a new untitled window. */ void FileNew (void) { Str255 titlebuf; WindowPtr w; OSErr err; WStatusH st; MakeUntitledTitle (titlebuf); w = WinOpenDocument ((StringPtr) titlebuf); if (w == NULL) {err = 0/*XXX*/; goto failed; } st = WinGetStatus (w); Assert (st != NULL); (*st)->datarefnum = (*st)->resrefnum = -1; return; failed: if (w != NULL) WinDoClose (closingWindow, w); ErrorAlertGeneric (err); } /* Open the specified file in a new window. */ OSErr FileOpen (FSSpec *filespec) { WindowPtr w = NULL; WStatusH st; StringPtr title; Str255 titlebuf; short resrefnum = -1, datarefnum = -1; Size textsize; Handle texthandle = NULL; OSErr err; int template; SignedByte perm; FInfo fileinfo; err = FSpGetFInfo (filespec, &fileinfo); if (err != noErr) goto failed; if (fileinfo.fdFlags & kIsStationery){ MakeUntitledTitle (titlebuf); title = (StringPtr) titlebuf; template = 1; }else{ title = (StringPtr) filespec->name; template = 0; } perm = template ? fsRdPerm : fsRdWrPerm; err = FSpOpenDF (filespec, perm, &datarefnum); if (err != noErr){ datarefnum = -1; goto failed; } err = GetEOF (datarefnum, &textsize); if (err != noErr) goto failed; err = SetFPos (datarefnum, fsFromStart, 0L); if (err != noErr) goto failed; err = AllocHandle (textsize, &texthandle); if (err != noErr) goto failed; HLock (texthandle); err = FSRead (datarefnum, &textsize, *texthandle); HUnlock (texthandle); if (err != noErr) goto failed; /*XXX FSpCreateResFile (filespec, creator, type, 0); */ resrefnum = FSpOpenResFile (filespec, perm); if (resrefnum != -1){ /* XXX lire la position de la fentre, la sŽlection, les scrollbars */ } w = WinOpenDocument (title); if (w == NULL) { err = 0/*XXX*/; goto failed; } st = WinGetStatus (w); Assert (st != NULL); WEUseText (texthandle, (*st)->we); WECalText ((*st)->we); WESetSelection (0, 0, (*st)->we); /* XXX */ AdjustScrollBars (w); WEResetModCount ((*st)->we); (*st)->basemodcount = 0; if (template){ FSClose (datarefnum); if (resrefnum != -1) CloseResFile (resrefnum); (*st)->datarefnum = (*st)->resrefnum = -1; }else{ (*st)->datarefnum = datarefnum; (*st)->resrefnum = resrefnum; } return noErr; failed: if (texthandle != NULL) DisposeHandle (texthandle); if (datarefnum != -1) FSClose (datarefnum); if (resrefnum != -1) CloseResFile (resrefnum); if (w != NULL) WinDoClose (closingWindow, w); return err; } /* Get a file with the standard dialog and open it in a new window. */ void FileDoGetOpen (void) { OSErr err; StandardFileReply sfreply; SFTypeList types = { 'TEXT' }; StandardGetFile (NULL, 1, types, &sfreply); if (sfreply.sfGood){ err = FileOpen (&sfreply.sfFile); if (err != noErr) ErrorAlertCantOpen (sfreply.sfFile.name, err); } } /* Revert w to the contents of its associated file. */ void FileRevert (WindowPtr w) { WStatusH st; short err; Size textsize; Handle texthandle; /*XXX demander confirmation */ st = WinGetStatus (w); Assert (st != NULL); Assert ((*st)->datarefnum != -1); Assert ((*st)->we != NULL); err = GetEOF ((*st)->datarefnum, &textsize); if (err != noErr) goto failed; err = SetFPos ((*st)->datarefnum, fsFromStart, 0L); if (err != noErr) goto failed; err = AllocHandle (textsize, &texthandle); if (err != noErr) goto failed; HLock (texthandle); err = FSRead ((*st)->datarefnum, &textsize, *texthandle); HUnlock (texthandle); if (err != noErr) goto failed; /* XXX lire la sŽlection (pas la scrollbar ?) */ SetPortWindowPort (w); WEUseText (texthandle, (*st)->we); WECalText ((*st)->we); WEUpdate (NULL, (*st)->we); WESetSelection (0, 0, (*st)->we); /* XXX */ AdjustScrollBars (w); WEResetModCount ((*st)->we); (*st)->basemodcount = 0; return; failed: if (texthandle != NULL) DisposeHandle (texthandle); ErrorAlertGeneric (err); } /* Save the text to datarefnum. If resrefnum != -1, save the window position and the current selection. */ static OSErr SaveText (WindowPtr w, short datarefnum, short resrefnum) { WStatusH st = WinGetStatus (w); Handle text; Size textsize; OSErr err; Assert (st != NULL); Assert ((*st)->we != NULL); err = SetEOF (datarefnum, 0L); if (err != noErr) goto failed; text = WEGetText ((*st)->we); textsize = GetHandleSize (text); HLock (text); err = FSWrite (datarefnum, &textsize, *text); HUnlock (text); if (err != noErr) goto failed; (*st)->basemodcount = WEGetModCount ((*st)->we); if (resrefnum != -1){ /* XXX Žcrire la sŽlection et la position des scrollbars attention: pas de fail. */ } return noErr; failed: return err; } /* Ask the user for a new file name, open both forks, and return the refnums. */ static OSErr PrepSaveAs (WindowPtr w, short *datarefnum, short *resrefnum, StandardFileReply *reply) { Str255 prompt, title; OSErr err; short auxrefnum = -1; *datarefnum = *resrefnum = -1; GetIndString (prompt, kMiscStrings, kSaveAsPromptIdx); GetWTitle (w, title); StandardPutFile (prompt, title, reply); if (reply->sfGood){ if (reply->sfReplacing){ err = FSpOpenDF (&reply->sfFile, fsRdWrPerm, datarefnum); if (err != noErr) *datarefnum = -1; if (err == opWrErr || err == fLckdErr || err == afpObjectLocked || err == permErr || err == afpAccessDenied || err == wrPermErr){ ErrorAlert (kCannotWriteIdx, reply->sfFile.name, kCloseQuoteIdx, err); } if (err != noErr) goto failed; err = FSpOpenRF (&reply->sfFile, fsRdWrPerm, &auxrefnum); if (err != noErr) auxrefnum = -1; if (err == opWrErr || err == fLckdErr || err == afpObjectLocked || err == permErr || err == afpAccessDenied){ ErrorAlert (kCannotWriteIdx, reply->sfFile.name, kCloseQuoteIdx, err); } if (err != noErr) goto failed; err = SetEOF (auxrefnum, 0L); if (err != noErr) goto failed; FSClose (auxrefnum); auxrefnum = -1; FSpCreateResFile (&reply->sfFile, kCreatorCaml,kTypeText,reply->sfScript); err = ResError (); if (err != noErr) goto failed; *resrefnum = FSpOpenResFile (&reply->sfFile, fsRdWrPerm); if (*resrefnum == -1){ err = ResError (); goto failed; } /*XXX ?? */ err = SetEOF (*datarefnum, 0L); if (err != noErr) goto failed; }else{ err = FSpCreate (&reply->sfFile, kCreatorCaml, kTypeText,reply->sfScript); if (err != noErr) goto failed; FSpCreateResFile (&reply->sfFile, kCreatorCaml,kTypeText,reply->sfScript); err = ResError (); if (err != noErr) goto failed; err = FSpOpenDF (&reply->sfFile, fsRdWrPerm, datarefnum); if (err != noErr){ *datarefnum = -1; goto failed; } *resrefnum = FSpOpenResFile (&reply->sfFile, fsRdWrPerm); if (*resrefnum == -1){ err = ResError (); goto failed; } /*XXX ?? */ } }else{ err = userCanceledErr; goto failed; } return noErr; failed: if (*datarefnum != -1) FSClose (*datarefnum); if (*resrefnum != -1) CloseResFile (*resrefnum); if (auxrefnum != -1) FSClose (auxrefnum); return err; } /* If saveasflag is true or there is no associated file, then ask for a new file name with the standard dialog and associate it with w. Save the contents of w to its associated file. */ static OSErr SaveDocument (WindowPtr w, int saveasflag) { WStatusH st = WinGetStatus (w); OSErr err; int changetitle = 0; short datarefnum = -1, resrefnum = -1; Assert (st != NULL); if (saveasflag || (*st)->datarefnum == -1){ StandardFileReply reply; err = PrepSaveAs (w, &datarefnum, &resrefnum, &reply); if (err != noErr) goto failed; if ((*st)->datarefnum == -1){ Assert ((*st)->resrefnum == -1); FreeUntitledTitle (); }else{ Assert ((*st)->resrefnum != -1); FSClose ((*st)->datarefnum); if ((*st)->resrefnum != -1) CloseResFile ((*st)->resrefnum); (*st)->datarefnum = (*st)->resrefnum = -1; } (*st)->datarefnum = datarefnum; (*st)->resrefnum = resrefnum; SetWTitle (w, reply.sfFile.name); datarefnum = resrefnum = -1; } err = SaveText (w, (*st)->datarefnum, (*st)->resrefnum); if (err != noErr) goto failed; return noErr; failed: if (datarefnum != -1) FSClose (datarefnum); if (resrefnum != -1) CloseResFile (resrefnum); return err; } /* Save the toplevel window to a new file. Do not save the window position or the current selection. */ static OSErr SaveToplevel (void) { WStatusH st; StandardFileReply reply; short datarefnum = -1, resrefnum = -1; OSErr err; Assert (winToplevel != NULL); st = WinGetStatus (winToplevel); Assert (st != NULL); err = PrepSaveAs (winToplevel, &datarefnum, &resrefnum, &reply); if (err != noErr) goto failed; err = SaveText (winToplevel, datarefnum, -1); if (err != noErr) goto failed; FSClose (datarefnum); if (resrefnum != -1) CloseResFile (resrefnum); return noErr; failed: if (datarefnum != -1) FSClose (datarefnum); if (resrefnum != -1) CloseResFile (resrefnum); return err; } static OSErr SaveGraphics (void) { XXX (); return noErr; } OSErr FileDoSave (WindowPtr w, int saveasflag) { if (w == winToplevel) return SaveToplevel (); else if (w == winGraphics) return SaveGraphics (); else return SaveDocument (w, saveasflag); }