Document.cp

/*------------------------------------------------------------------------------------------
 
    Program:    CPlusTESample 2.0
    File:       Document.cp
    Uses:       Document.h
 
    by Andrew Shebanow
    of Apple Macintosh Developer Technical Support
 
    Copyright © 1989-1990 Apple Computer, Inc.
    All rights reserved.
 
------------------------------------------------------------------------------------------*/
 
// Mac Includes
#ifndef __TYPES__
#include <Types.h>
#endif
#ifndef __QUICKDRAW__
#include <QuickDraw.h>
#endif
#ifndef __FONTS__
#include <Fonts.h>
#endif
#ifndef __EVENTS__
#include <Events.h>
#endif
#ifndef __CONTROLS__
#include <Controls.h>
#endif
#ifndef __WINDOWS__
#include <Windows.h>
#endif
#ifndef __MENUS__
#include <Menus.h>
#endif
#ifndef __TEXTEDIT__
#include <TextEdit.h>
#endif
#ifndef __DIALOGS__
#include <Dialogs.h>
#endif
#ifndef __MENUS__
#include <Menus.h>
#endif
#ifndef __DEVICES__
#include <Devices.h>
#endif
#ifndef __EVENTS__
#include <Events.h>
#endif
#ifndef __SCRAP__
#include <Scrap.h>
#endif
#ifndef __TOOLUTILS__
#include <ToolUtils.h>
#endif
#ifndef __MEMORY__
#include <Memory.h>
#endif
#ifndef __SEGLOAD__
#include <SegLoad.h>
#endif
#ifndef __FILES__
#include <Files.h>
#endif
#ifndef __OSUTILS__
#include <OSUtils.h>
#endif
#ifndef __TRAPS__
#include <Traps.h>
#endif
#ifndef __PACKAGES__
#include <Packages.h>
#endif
#ifndef __ERRORS__
#include <Errors.h>
#endif
 
#include "Document.h"
 
//---------------------------------------------------------------------------------
 
TDocument::TDocument(short resID, OSType fileType)
{
    short wdRefNum, vRefNum;
    long dirID;
 
    (void) GetVol(nil,&wdRefNum);
    TApplication::WDToDirID(wdRefNum,vRefNum,dirID);
    fFile.vRefNum = vRefNum;
    fFile.dirID = dirID;
    CopyPString(fFile.fileName,"\pUntitled");
 
    fFileRefNum = 0;
    fNewDoc = true;
    fReadOnly = false;
    fDirty = false;
    fFileType = fileType;
    fActive = false;
 
    fDocWindow = GetNewWindow(resID,nil,(WindowPtr) -1);
    SetPort(fDocWindow);
}
 
TDocument::~TDocument()
{
    if (fFileRefNum != 0)
      CloseFile();
    DisposeWindow(fDocWindow);
}
 
void TDocument::DoActivate(Boolean becomingActive)
{
    fActive = becomingActive;
}
 
void TDocument::OpenFile(Boolean readOnly, Boolean createIfNecessary)
{
    short refNum;
    char perm;
    FInfo fndrInfo;
 
    // first, check if file exists
    OSErr err = HGetFInfo(fFile.vRefNum,fFile.dirID,fFile.fileName,&fndrInfo);
    if ((err == fnfErr) && createIfNecessary)
      {
        FailOSErr(HCreate(fFile.vRefNum,fFile.dirID,fFile.fileName,
                      TApplication::GetCreator(),fFileType));
      }
    else FailOSErr(err);
 
    perm = (readOnly) ? fsRdPerm : fsRdWrPerm;
    FailOSErr(HOpen(fFile.vRefNum, fFile.dirID,
                    fFile.fileName, perm, &refNum));
    fFileRefNum = refNum;
}
 
void TDocument::CloseFile()
{
    if (fFileRefNum != 0)
      {
        FailOSErr(FSClose(fFileRefNum));
        fFileRefNum = 0;
      }
}
 
void TDocument::OpenOldDoc(CanonicalFileSpec theFile, Boolean readOnly)
{
    fFile = theFile;
    fFileRefNum = 0;
    fNewDoc = false;
    fReadOnly = readOnly;
    fDirty = false;
 
    OpenFile(fReadOnly,false);
    (void) SetFPos(fFileRefNum,fsFromStart,0);
    ReadFromFile(fFileRefNum);
 
    SetWTitle(fDocWindow,fFile.fileName);
    SetPort(fDocWindow);
}
 
YNCResult TDocument::PresentSaveDialog(Boolean quitting)
{
    Str255 fileName;
    Str255 buzzword;
 
    SetCursor(&qd.arrow);
    CopyPString(fileName,fFile.fileName);
    if (quitting)
      GetIndString(buzzword,kBuzzwordStrings,bQuitting);
    else GetIndString(buzzword,kBuzzwordStrings,bClosing);
    ParamText(fileName, buzzword, "\p", "\p");
    short item = Alert(rSaveAlert, (ModalFilterProcPtr) nil);
    switch (item)
      {
        case 1:
        default:
            return yesResult;
        case 2:
            return noResult;
        case 3:
            return cancelResult;
      }
}
 
YNCResult TDocument::DoClose(Boolean askUserToSave, YNCResult defaultAnswer, Boolean quitting)
{
    YNCResult res;
 
    if (fDirty && askUserToSave)
      res = PresentSaveDialog(quitting);
    else res = defaultAnswer;
    if (fDirty && (res == yesResult))
      DoSave();
    return res;
}
 
void TDocument::DoSave()
{
    if (fNewDoc)
      {
        DoSaveAs();
        return;
      }
 
    if (!fDirty)
      return;
 
    FailOSErr(SetFPos(fFileRefNum,fsFromStart,0));
    FailOSErr(SetEOF(fFileRefNum,0));
    WriteToFile(fFileRefNum);
    fDirty = false;
}
 
void TDocument::DoSaveAs()
{
    Point where;
    Str255 prompt, origName;
    SFReply reply;
 
    SetPt(&where,100,100);
    CopyPString(origName,fFile.fileName);
    prompt[0] = '\0';
    SFPutFile(where, prompt, origName, NULL, &reply);
    if (reply.good == false)
      return;
 
    // close existing file, if any
    if (fFileRefNum != 0)
      CloseFile();
 
    // setup fields correctly
    TApplication::WDToDirID(reply.vRefNum, fFile.vRefNum, fFile.dirID);
    CopyPString(fFile.fileName, reply.fName);
 
    OpenFile(false,true);
    SetWTitle(fDocWindow,fFile.fileName);
 
    FailOSErr(SetFPos(fFileRefNum,fsFromStart,0));
    WriteToFile(fFileRefNum);
 
    fNewDoc = false;
    fDirty = false;
}
 
//---------------------------------------------------------------------------------
 
// find the TDocument associated with the window
TDocument* TDocumentList::FindDoc(WindowPtr window)
{
    TDocument* tDoc;
 
    for (int idx = 0; idx < fNumObjs; idx++)
      {
        tDoc = (TDocument*) At(idx);
        if (tDoc->GetDocWindow() == window)
          return tDoc;
      }
    return nil;
}
 
// private list management routines
void TDocumentList::AddDoc(TDocument* doc)
{
    InsertFirst(doc);
}
 
void TDocumentList::RemoveDoc(TDocument* doc)
{
    Remove(doc);
}