4. CounterDocument/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 = MakeControlsWindow();
    ThrowIfNil_(mWindow);
    if (inFileSpec == nil) {
        NameNewDoc();
    } else {
        OpenFile(*inFileSpec);
    }
    mWindow->Show();
    mIsDirty = false;
}
 
// ---------------------------------------------------------------------------
//  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());
                mIsDirty = true;
            }
            break;
 
        case cmd_Increment:
//          ::SysBeep(1);
            stCounter.Increment();
            mCaption->SetValue(stCounter.GetValue());
            mIsDirty = true;
            break;
 
        case cmd_Decrement:
            stCounter.Decrement();
            mCaption->SetValue(stCounter.GetValue());
            mIsDirty = 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::MakeControlsWindow()
{
    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 = nil;
    // Create a new file object.
    StDeleter<LFile> theFile(new LFile(inFileSpec));
    
    // Open the data fork; get the date; close the data fork
    theFile->OpenDataFork(fsRdWrPerm);  
    Int32** valueHdl = (Int32**)theFile->ReadDataFork();
//  cout << "**valueHdl: " << **valueHdl << endl;
    theFile->CloseDataFork();
    
    // Put the contents in the view
    // and clear the dirty flag.
    stCounter.SetValue((Int32)**valueHdl);
    ::DisposeHandle((Handle)valueHdl);
    mCaption->SetValue(stCounter.GetValue());   
    mIsDirty = false;
    
    // Set the window title to the name of the file and
    // flag that the document has an associated file.
    mWindow->SetDescriptor(inFileSpec.name);
    mIsSpecified = true;
 
    mFile = theFile.Release();
}
 
// ---------------------------------------------------------------------------------
Boolean
CCounterDocument::IsModified()
{
    return mIsDirty;
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::DoAESave(FSSpec& inFileSpec, OSType inFileType)
{
//  cout << "inFileType:" << inFileType << endl;
    delete mFile;   // this does nothing to the actual file on disk.
    mFile = nil;
    mFile = new LFile(inFileSpec);
    
    // Get the proper file type.
    OSType  theFileType = kDocType;
    if (inFileType != fileType_Default) {
        theFileType = inFileType;
    }
//  cout << "File type:" << theFileType << endl;
//  cout << "kCreatorType:" << kCreatorType << endl;
    mFile->CreateNewDataFile(kCreatorType, theFileType);
    DoSave();
    mWindow->SetDescriptor(inFileSpec.name);    // set window title
    mIsDirty = false;
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::DoSave()
{
    mFile->OpenDataFork(fsRdWrPerm);
    Int32 value = stCounter.GetValue();
//  cout << value << endl;
    mFile->WriteDataFork(&value, 32);       // should use sizeof()
    mFile->CloseDataFork();
    mIsDirty = false;
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::DoRevert()
{
    mFile->OpenDataFork(fsRdWrPerm);
/*  Handle  theTextH = mFile->ReadDataFork();
    mFile->CloseDataFork();
    mTextView->SetTextHandle( theTextH );
    mTextView->SetDirty( false );
    ::DisposeHandle( theTextH );
    mTextView->Refresh();
*/
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::DoPrint()
{
/*  // Create the printout.
    StDeleter<LPrintout> thePrintout(LPrintout::CreatePrintout( rPPob_TextPrintout ));
    ThrowIfNil_(thePrintout.Get());
    
    // Set the print record.
    if (mPrintRecordH) {
        thePrintout->SetPrintRecord( mPrintRecordH );
    }
    
    // Get the text placeholder.
    LPlaceHolder    *thePlaceholder;
    thePlaceholder = dynamic_cast<LPlaceHolder*>(thePrintout->FindPaneByID( kTextPlaceholder ));
    ThrowIfNil_(thePlaceholder);
    
    // Install the text view in the placeholder.
    thePlaceholder->InstallOccupant( mTextView, atNone );
    
    // Set the frame size.
    SetPrintFrameSize();
    
    // 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.
*/
}
 
// ---------------------------------------------------------------------------------
void
CCounterDocument::SetPrintFrameSize()
{
    /*
    // Get the frame size.
    SDimension16    theFrameSize;
    mTextView->GetFrameSize( theFrameSize );
    
    // Get the text edit record handle.
    TEHandle    theTextEditH = mTextView->GetMacTEH();
    
    // Calculate the number of lines per page.
    Int16   theLinesPerPage;
    theLinesPerPage = theFrameSize.height / (**theTextEditH).lineHeight;
 
    // Resize the frame to an integral number of lines.
    mTextView->ResizeFrameTo( theFrameSize.width,
        (**theTextEditH).lineHeight * theLinesPerPage, false );
*/
}