6. CounterAbout/source/CCounterDocument.cp

/*
    File:       CCounterDocument.cp
 
    Contains:   Sample code to accompany Chapter 12 of 
                "An Introduction to Macintosh Programming for Windows Programmers".
                
    Written by: Worldwide Developer Technical Support
 
    Copyright:  1999 Apple Computer, Inc., All Rights Reserved
 
    You may incorporate this sample code into your applications without
    restriction, though the sample code has been provided "AS IS" and the
    responsibility for its operation is 100% yours.  However, what you are
    not permitted to do is to redistribute the source as "DSC Sample Code"
    after having made changes. If you're going to re-distribute the source,
    we require that you make it clear in the source that the code was
    descended from Apple Sample Code, but that you've made changes.
    
*/
#include <LFile.h>
#include <LPlaceHolder.h>
#include <LPrintout.h>
#include <LString.h>
#include <LWindow.h>
#include <PP_Messages.h>
#include <UMemoryMgr.h>
#include <UWindows.h>
#include <UModalDialogs.h>
 
#include <iostream>             // console for debugging
using namespace std;            //introduces namespace std
 
#include "CounterConstants.h"
#include "CCounterDocument.h"
 
//==================================================================================
CCounterDocument::CCounterDocument(LCommander* inSuper, FSSpec* inFileSpec)
    : LSingleDoc(inSuper)
{
    mWindow = nil;
    mWindow = MakeDocumentWindow();
    ThrowIfNil_(mWindow);
    if (inFileSpec == nil) {
        NameNewDoc();
    } else {
        OpenFile(*inFileSpec);
    }
    mWindow->Show();
}
 
// ---------------------------------------------------------------------------
//  Respond to commands from menus, buttons, etc.
Boolean
CCounterDocument::ObeyCommand(CommandT  inCommand, void* ioParam)
{
    Boolean cmdHandled = true;
    switch (inCommand) {
        case cmd_SetValue:
            Int32 newValue = 0;
            if (AskForValue(newValue)) {
                stCounter.SetValue(newValue);
                mCaption->SetValue(stCounter.GetValue());
                mIsModified = true;
            }
            break;
 
        case cmd_Increment:
//          ::SysBeep(1);
            stCounter.Increment();
            mCaption->SetValue(stCounter.GetValue());
            mIsModified = true;
            break;
 
        case cmd_Decrement:
            stCounter.Decrement();
            mCaption->SetValue(stCounter.GetValue());
            mIsModified = true;
            break;
 
        default:
            cmdHandled = LSingleDoc::ObeyCommand(inCommand, ioParam);
            break;
    }
    return cmdHandled;
}
 
// ---------------------------------------------------------------------------
//  This function enables menu commands.
void
CCounterDocument::FindCommandStatus(
    CommandT    inCommand,
    Boolean     &outEnabled,
    Boolean     &outUsesMark,
    Char16      &outMark,
    Str255      outName)
{
    switch (inCommand) {
        // Return menu item status according to command messages.
 
        case cmd_SetValue:
            outEnabled = true;          // enable the button
            break;
 
        case cmd_Increment:
            outEnabled = true;          // enable the button
            break;
 
        case cmd_Decrement:
            outEnabled = true;          // enable the button
            break;
 
        default:
            LSingleDoc::FindCommandStatus(inCommand, outEnabled,
                                                outUsesMark, outMark, outName);
            break;
    }
}
 
// ---------------------------------------------------------------------------
LWindow*
CCounterDocument::MakeDocumentWindow()
{
    LWindow* theWindow = LWindow::CreateWindow(rWindow_Sample, this );
    mCaption = dynamic_cast<LCaption*>(theWindow->FindPaneByID(kCaption));
    ThrowIfNil_(mCaption);
    theWindow->Show();
    return theWindow;
}
 
// ---------------------------------------------------------------------------
Boolean
CCounterDocument::AskForValue(Int32& newValue)
{
    Str255 numStr;
    Boolean theResult = UModalDialogs::AskForOneNumber(this,
                            rDialog_Value, kEditField, newValue);
    return theResult;
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::NameNewDoc()
{
    LStr255 theTitle("\pUntitled");
    // Find the first available title. We could also check the window
    // pane id if we wanted to make sure we didn't collide with other
    // window types.
    Int32   theNumber = 0;
    while (UWindows::FindNamedWindow(theTitle) != nil ) {
        // An existing window has the current name
        // Increment counter and try again.
        ++theNumber;
        theTitle = "\pUntitled ";
        theTitle += static_cast<Int32>(theNumber);
    }           
    // Finally, set window title.
    mWindow->SetDescriptor(theTitle);
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::OpenFile(FSSpec& inFileSpec)
{
    mFile = new LFile(inFileSpec);
    ReadTheData();
    mWindow->SetDescriptor(inFileSpec.name);    // set window title
    mIsSpecified = true;
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::DoRevert()
{
    ReadTheData();
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::ReadTheData()
{
    mFile->OpenDataFork(fsRdWrPerm);
    Int32** valueHdl = (Int32**)mFile->ReadDataFork();
    mFile->CloseDataFork();
    stCounter.SetValue((Int32)**valueHdl);
    ::DisposeHandle((Handle)valueHdl);
    mCaption->SetValue(stCounter.GetValue());   
    mIsModified = false;
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::DoAESave(FSSpec& inFileSpec, OSType inFileType)
{
    delete mFile;   // this does nothing to the actual file on disk.
    mFile = nil;
    mFile = new LFile(inFileSpec);  
    mIsSpecified = true;
    // Get the proper file type.
    OSType  theFileType = kDocType;
    if (inFileType != fileType_Default) {
        theFileType = inFileType;
    }
    mFile->CreateNewDataFile(kCreatorType, theFileType);
    DoSave();
    mWindow->SetDescriptor(inFileSpec.name);    // set window title
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::DoSave()
{
    mFile->OpenDataFork(fsRdWrPerm);
    Int32 value = stCounter.GetValue();
    int kBytesToWrite = sizeof(Int32);
    mFile->WriteDataFork(&value, kBytesToWrite);
    mFile->CloseDataFork();
    mIsModified = false;
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::DoPrint()
{
    StDeleter<LPrintout> thePrintout(LPrintout::CreatePrintout( rPrintout ));
    ThrowIfNil_(thePrintout.Get());
    
    // Set the print record.
    if (mPrintRecordH) {
        thePrintout->SetPrintRecord( mPrintRecordH );
    }
    
    // Get the placeholder.
    LPlaceHolder    *thePlaceholder;
    thePlaceholder = dynamic_cast<LPlaceHolder*>
                (thePrintout->FindPaneByID(rPlaceholder));
    ThrowIfNil_(thePlaceholder);
    
    // Install the text view in the placeholder.
    thePlaceholder->InstallOccupant( mCaption, atNone );
    
    // Print.
    thePrintout->DoPrintJob();
    
    // Delete the printout (handled automatically by the
    // StDeleter object). The text view is returned
    // to the window when the placeholder is destroyed.
 
}