home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-01-28 | 60.6 KB | 2,219 lines | [TEXT/MPS ] |
- // UPrinting.cp
- // Copyright © 1986-1990 by Apple Computer, Inc. All rights reserved.
-
- /*
- Segmentation strategy:
- PrintRes Resident
- PrintMain Resident and used at initialization
- PrintActual Used only during Actual Printing (imaging/spooling)
- PrintImage Used during imaging only
- PrintSpool Used only during printing of a Spool File
- PrintDebug Debugging code
- PrintFinder Code only ever accessed from Finder Printing
- PrintInit One-time Initialization Code
- PrintOpen Code accessed when opening new document
- PrintNonRes General non-resident code
- PrintDoCommand Code for Page Setup command
- PrintTerminate One-time-only code, called only at Termination time
- */
-
- #ifndef __ULIST__
- #include <UList.h>
- #endif
-
- #ifndef __EDITIONS__
- #include <Editions.h>
- #endif
-
- #ifndef __UAPPLICATION__
- #include <UApplication.h>
- #endif
-
- #ifndef __UDOCUMENT__
- #include <UDocument.h>
- #endif
-
- #ifndef __BALLOONS__
- #include <Balloons.h>
- #endif
-
- #ifndef __UVIEW__
- #include <UView.h>
- #endif
-
- #ifndef __UWINDOW__
- #include <UWindow.h>
- #endif
-
- #ifndef __UFAILURE__
- #include <UFailure.h>
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include <UMacAppUtilities.h>
- #endif
-
- #ifndef __UERRORMGR__
- #include <UErrorMgr.h>
- #endif
-
- #ifndef __UPATCH__
- #include <UPatch.h>
- #endif
-
- #ifndef __UMEMORY__
- #include <UMemory.h>
- #endif
-
- #ifndef __UMACAPPGLOBALS__
- #include <UMacAppGlobals.h>
- #endif
-
- #ifndef __UVIEWCOORDS__
- #include <UViewCoords.h>
- #endif
-
- #ifndef __MENUS__
- #include <Menus.h>
- #endif
-
- #ifndef __UMENUMGR__
- #include <UMenuMgr.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __FONTS__
- #include <Fonts.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __STDLIB__
- #include <StdLib.h> // for abs()
- #endif
-
- #ifndef __UPRINTING__
- #include <UPrinting.h>
- #endif
-
- //--------------------------------------------------------------------------------------------------
- PenState gBreaksPenState;
- Boolean gCancelAllPrinting;
- VRect gStdPageMargins;
- Handle gFinderHPrint;
- TStdPrintHandler* gJobPrintHandler;
-
- //--------------------------------------------------------------------------------------------------
- typedef Str255* String255Ptr;
- typedef String255Ptr* String255Handle;
-
- // subclass may stuff some special values by redefining this
- union TXWord
- {
- struct
- {
- char c1, c0;
- } charVal;
- struct
- {
- SignedByte b1, b0;
- } byteVal;
- struct
- {
- Boolean f15, f14, f13, f12, f11, f10, f9, f8, f7, f6, f5, f4, f3, f2, f1, f0;
- } boolVal;
- short iO;
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TPrintCommand::DoIt(void)
- {
- Boolean proceed;
-
- fStdPrintHandler->Print(fCmdNumber, proceed);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintSelCommand
-
- pascal void TPrintCommand::Initialize(void) // override
- {
- inherited::Initialize();
- fStdPrintHandler = NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintSelCommand
-
- pascal void TPrintCommand::IPrintCommand(CmdNumber itsCmdNumber,
- TStdPrintHandler* itsStdPrintHandler)
- {
- this->INoChangesCommand(itsCmdNumber, itsStdPrintHandler->fDocument, itsStdPrintHandler->fView);
- fStdPrintHandler = itsStdPrintHandler;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MAFields
-
- pascal void TPrintCommand::Fields(TObject* obj) // override
- {
- obj->DoToField("TPrintCommand", NULL, bClass);
- obj->DoToField("fStdPrintHandler", &fStdPrintHandler, bObject);
- inherited::Fields(obj);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
- //$Push
- // #if qTrace
- //$D+
- //#endif No tracing till we get the port straightened out since the current
- //port could already be disposed (Thank you Direct connect ImageWriter!)
-
- pascal void IdleProcForTStdPrintHandler(void)
- {
- GrafPtr savedPort;
-
- if (gJobPrintHandler)
- {
- GetPort(savedPort);
- SetPort(gWorkPort); // Nice safe port in a storm
- gJobPrintHandler->DoPrintIdling(); // Forward to the current print job handler
- SetPort(savedPort);
- }
- }
- //$Pop
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
-
- pascal void TStdPrintHandler::DoPrintIdling(void)
- {
- const short myDlgMask = mDownMask + mUpMask + keyDownMask + keyUpMask + autoKeyMask;
-
- char ch;
- short keycode;
- DialogPtr aDialog;
- TDeviceEvent * event;
- EventRecord anEventRecord;
- short item;
- Handle theItem;
- short itemType;
- Rect box;
- long dontCare;
-
- event = gApplication->GetEvent(myDlgMask, 0, NULL);
- if (event)
- {
- // Workaround for LaserWriter driver bug: it tries to set GhostWindow
- // so that its status window is invisible. Unfortunately, it doesn't
- // always set it, so IsDialogEvent returns FALSE (the status window
- // is frontmost). If ours isn't already in front, force it there.
- if (fPrintDialog != FrontWindow())
- gApplication->SelectWMgrWindow(fPrintDialog);
-
- switch (event->fEventRecord.what)
- {
- case keyDown:
- ch = (char)(event->fEventRecord.message & charCodeMask);
- keycode = (short)((event->fEventRecord.message >> keyCodeMask) & 8);
- if (((ch == '.') && event->fCmdKey) || ((ch == chEscape) && (keycode == kEscapeVirtualCode)))
- {
-
- /*### need a way to determine if multiple file printing is in process
- if (gFinderPrinting)
- item = cancel; // Want the 'Cancel All' button
- else
- item = 1; // Want the 'Cancel' button
- */
- item = 1;
-
- // Flash the appropriate button
- GetDItem(fPrintDialog, item, itemType, theItem, box);
- HiliteControl((ControlHandle)theItem, 10);
- Delay(8, dontCare);
- HiliteControl((ControlHandle)theItem, 0);
-
- PrSetError(iPrAbort);
- gCancelAllPrinting = TRUE;
- }
- break;
-
- default:
- anEventRecord = event->fEventRecord;
- if (IsDialogEvent(anEventRecord) && DialogSelect(anEventRecord, aDialog, item) && (aDialog == fPrintDialog))
- switch (item)
- {
- case 1:
- PrSetError(iPrAbort);// Cancel
- break;
-
- case cancel: // Cancel All Printing
- PrSetError(iPrAbort);
- gCancelAllPrinting = TRUE;
- break;
- }
- break;
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
-
- pascal void TStdPrintHandler::ChkPrintErr(OSErr& err,
- Boolean& proceed,
- Boolean& ranOutOfSpace)
- {
- if (proceed)
- {
- err = PrError();
- if (err != noErr)
- {
- #if qDebug
- if (gDebugPrinting)
- cout << "Error from PrError is " << err << "\n";
- #endif
-
- proceed = FALSE;
- if (err == -1)
- ranOutOfSpace = TRUE;
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::GetDriverName(Str255& driverName)
- {
- String255Handle driverHandle;
-
- driverHandle = (String255Handle)GetString((short)kPrintDriverName);// Get current driver
-
- // Be a little cautious, in case we accidentally pick up something
- // which is not what we expect, or we can't find it.
- if (driverHandle && ((**driverHandle).Length() < 64))
- CopyStr255(**driverHandle, (Ptr) & driverName);
- else
- driverName = "";
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintInit
- // Initialize the printing unit. Call exactly once
-
- pascal void InitUPrinting(void)
- {
- TStdPrintHandler * aStdPrintHandler;
-
- gCancelAllPrinting = FALSE;
- gFinderHPrint = NULL;
- gJobPrintHandler = NULL;
-
- SetVRect(gStdPageMargins, 72, 72, -72, -72);// 1" margins std default
-
- gBreaksPenState.pnLoc = gZeroPt;
- gBreaksPenState.pnSize = Point(2, 2);
- gBreaksPenState.pnMode = patCopy;
- StuffHex((Ptr) & gBreaksPenState.pnPat, "CC663399CC663399");
-
- gCouldPrint = TRUE;
-
- gUPrintingInitialized = TRUE;
-
- if (gPrintHandler == gNullPrintHandler)
- {
- // Install a StdPrintHandler in UMacApp
- // global variable gPrintHandler
- aStdPrintHandler = new TStdPrintHandler;
- aStdPrintHandler->IStdPrintHandler(NULL, NULL, kSquareDots, kFixedSize, kFixedSize);
- aStdPrintHandler->fFinderJobDialog = TRUE;
- gPrintHandler = aStdPrintHandler;
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MAPrintingRes
- // Synonym For InitUPrinting
-
- pascal void InitPrinting(void)
- {
- InitUPrinting();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintSpool
-
- pascal void TStdPrintHandler::PrintSpoolFile(Handle anHPrint,
- OSErr& err,
- Boolean& proceed)
- {
- TPrStatus prStatus;
- Boolean b;
-
- proceed = TRUE;
- PrPicFile((THPrint)anHPrint, NULL, NULL, NULL, prStatus);
- this->ChkPrintErr(err, proceed, b);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintOpen
-
- pascal void TStdPrintHandler::Initialize(void) // override
- {
- #if qDebug
- if (!gUPrintingInitialized)
- {
- ProgramBreak("InitUPrinting must be called before creating a print handler.");
- Failure(noErr, 0);
- }
- #endif
-
- inherited::Initialize();
- fFinderJobDialog = FALSE;
- fFinderSetup = FALSE;
- fFixedSizePages[hSel] = kFixedSize;
- fFixedSizePages[vSel] = kFixedSize;
- fHPrint = NULL;
- fLastBreak = gZeroVPt;
- fLastPrinterName = NULL;
- fLastStrip = VPoint(MAXINT, MAXINT);
- fMarginRes.h = 72;
- fMarginRes.v = 72;
- fMinimalMargins = FALSE;
- fPageAreas.theMargins = gStdPageMargins; //!!! What about other fields?
- fPageDirection = vSel; // Page 2 is below page 1, etc.
- fPageStrips = gZeroVPt; //!!! Another default?
- fPPrPort = NULL;
- fPrintDialog = NULL;
- fPrinterDev = kNeverInitialized;
- fPrintExtent = gZeroVRect; //!!! Another default?
- fShowBreaks = FALSE;
- fSquareDots = kSquareDots;
- fStartPage = 1;
- fViewedRect = gZeroVRect; //!!! Another default?
-
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintOpen
-
- pascal void TStdPrintHandler::IStdPrintHandler(TDocument* itsDocument,
- TView* itsView,
- Boolean itsSquareDots,
- Boolean itsHFixedSize,
- Boolean itsVFixedSize)
- {
- FailInfo fi;
-
- this->IPrintHandler(itsView);
- fDocument = itsDocument;
- fSquareDots = itsSquareDots;
- fFixedSizePages[hSel] = itsHFixedSize;
- fFixedSizePages[vSel] = itsVFixedSize;
-
- if (!fi.CatchFailure())
- {
- if (itsView)
- {
- // allocates a handle for the print-info, and sets my field fHPrint accordingly
- this->SetDefaultPrintInfo();
-
- if (itsDocument != NULL)
- itsDocument->AttachPrintHandler(this);
-
- fView->AttachPrintHandler(this);
- }
- fi.Success();
- }
- else
- {
- this->Free();
- fi.ReSignal();
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintClose
-
- pascal void TStdPrintHandler::Free(void) // override
- {
- Boolean dontDispose;
- TDocument * itsDocument;
-
- dontDispose = (fView != NULL);
- if (dontDispose)
- {
- if (fView->fPrintHandler == this)
- fView->AttachPrintHandler(gNullPrintHandler);
- fView = NULL;
-
- itsDocument = fDocument;
- dontDispose = (itsDocument != NULL);
- if (dontDispose)
- {
- if (itsDocument->fDocPrintHandler == this)
- itsDocument->fDocPrintHandler = NULL;
- dontDispose = itsDocument->fSharePrintInfo;
- }
- if (dontDispose)
- dontDispose = (itsDocument->fPrintInfo == fHPrint);
- fDocument = NULL;
-
- }
- if (!dontDispose)
- fHPrint = DisposeIfHandle(fHPrint);
- fHPrint = NULL; // Always drop my reference
-
- fLastPrinterName = (StringHandle)DisposeIfHandle((Handle)fLastPrinterName);
-
- this->BanishPrintDialog();
-
- if (gJobPrintHandler == this) // let's be safe
- gJobPrintHandler = NULL;
-
- inherited::Free();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintImage
-
- pascal void TStdPrintHandler::AdornPage(void)
- {
- #if qDebug
- const short botSlop = 8; // ??? Arbitrary choice
-
- Str255 heading;
- Str255 pgStr;
- VRect handyRect;
- Rect handyQDRect;
- long itsWidth;
- long rPlusL;
- long itsBottom;
- FontInfo theFontInfo;
- Rect theTextRect;
-
- if (gDebugPrinting) // Print extra stuff if debugging
- {
- NumToString(fFocusedPage, pgStr);
- TextFont(applFont);
- TextFace(normal);
- TextSize(12);
- heading = "-" + pgStr + "-"; // ??? Make easier for client to change this
-
- // draw the heading
- itsWidth = StringWidth(heading);
- rPlusL = fPageAreas.thePaper.right + fPageAreas.thePaper.left;
- itsBottom = fPageAreas.theInk.bottom - botSlop;
- GetFontInfo(theFontInfo);
- theTextRect.left = (short)(rPlusL - itsWidth) / 2;
- theTextRect.top = (short)itsBottom - theFontInfo.ascent;
- theTextRect.right = (short)(theTextRect.left + itsWidth);
- theTextRect.bottom = (short)itsBottom + theFontInfo.descent;
- MADrawString(heading, theTextRect, teFlushDefault);
-
- // Additionally frame the printable area of the page if gDebugPrinting
- handyRect = fPageAreas.theInk;
- fView->ViewToQDRect(handyRect, handyQDRect);
-
- PenSize(1, 1);
- FrameRect(handyQDRect);
-
- // Frame the 'interior' of the page
- handyRect = fPageAreas.theInterior;
- fView->ViewToQDRect(handyRect, handyQDRect);
-
- PenSize(2, 2);
- FrameRect(handyQDRect);
- }
- #endif
-
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
-
- pascal void TStdPrintHandler::BanishPrintDialog(void)
- {
- if (fPrintDialog)
- {
- if (fPrintDialog == qd.thePort) // Only need to invalidate focus if freed
- // dialog is the current port
- {
- gApplication->InvalidateFocus();
- SetPort(gWorkPort);
- }
- DisposDialog(fPrintDialog);
- fPrintDialog = NULL;
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- // Called from fView->DoBreakFollowing(),
- pascal VCoordinate TStdPrintHandler::BreakFollowing(VHSelect vhs,
- VCoordinate prevBreak,
- Boolean& automatic)// override
- {
- VHSelect orthoVHS;
- VCoordinate newLoc;
-
- orthoVHS = gOrthogonal[vhs];
- automatic = TRUE;
- newLoc = Min(prevBreak + fViewPerPage[orthoVHS], fPrintExtent[botRight][orthoVHS]);
-
- #if qDebug
- if (newLoc <= prevBreak)
- {
- cout << form("No advance in BreakFollowing; vhs: %1d prevBreak: %1d newLoc: %1d view size: ", (short)vhs, prevBreak, newLoc, fPrintExtent[botRight][orthoVHS]);
- ProgramBreak("No advance in BreakFollowing");
- }
- #endif
-
- return newLoc;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal Boolean FindLimit(VCoordinate,
- Boolean,
- void* staticLink)
- {
- ++(*((long*)staticLink));
- return FALSE;
- }
-
-
- pascal void TStdPrintHandler::CalcPageStrips(VPoint& pageStrips)// override
- {
- VHSelect ortho;
- long nStrips;
-
- // If pages are of fixed size, then simple divide the total size by the
- // page size. Otherwise, count up the page breaks one by one.
-
- for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
- {
- ortho = gOrthogonal[vhs];
- if (fFixedSizePages[ortho])
- pageStrips[vhs] = (fPrintExtent[botRight][ortho] - fPrintExtent[topLeft][ortho] + fViewPerPage[ortho] - 1) / fViewPerPage[ortho];
- else
- {
- nStrips = 0;
- this->EachBreak(vhs, TRUE, FindLimit, &nStrips);
- pageStrips[vhs] = nStrips;
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void TStdPrintHandler::CalcViewPerPage(VPoint& amtPerPage)// override
- {
- for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
- amtPerPage[vhs] = Max(1, (fPageAreas.thePaper[botRight][vhs] - fPageAreas.thePaper[topLeft][vhs] - labs(fPageAreas.theMargins[topLeft][vhs]) - labs(fPageAreas.theMargins[botRight][vhs])));
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- // this msg is sent to all views if my associated document is the kind where one
- // copy of the PrintInfo is shared among all views
- pascal void ItChanged(TView* aView,
- void*)
- {
- aView->DoPrinterChanged();
- }
-
-
- pascal void TStdPrintHandler::CheckPrinter(void)// override
- {
- PageAreas oldPageAreas = fPageAreas;
- long oldPrinterDev = fPrinterDev;
- Point oldDevRes(fDeviceRes);
- Point oldMarginRes(fMarginRes);
- Boolean didChange;
- Boolean msgSent;
- Str255 driverName;
- VRect aRect, bRect;
-
- // It costs an open and several LoadResources to call PrValidate. Before
- // doing so, check to see if the printer has actually changed.
- this->GetDriverName(driverName);
- if (!fLastPrinterName || (!EqualString(**fLastPrinterName, driverName, FALSE, TRUE)))
- {
- // Printer name has changed…
- fLastPrinterName = (StringHandle)DisposeIfHandle((Handle)fLastPrinterName);// out with the old
- fLastPrinterName = NewString(driverName);// in with the new
- FailNIL(fLastPrinterName);
- this->ValidatePrintRecord(didChange); // …and validate the print record.
- }
-
- // Store latest data from MacPrint prInfo record into my own instance variables
- RectToVRect(((TPPrint) * fHPrint)->rPaper, fPageAreas.thePaper);
- fMarginRes = Point(((TPPrint) * fHPrint)->prInfo.iVRes, ((TPPrint) * fHPrint)->prInfo.iHRes);// read the new device resolution values
- fDeviceRes = fMarginRes;
- fPrinterDev = ((TPPrint) * fHPrint)->prInfo.iDev;
- RectToVRect(((TPPrint) * fHPrint)->prInfo.rPage, fPageAreas.theInk);
- if (!fMinimalMargins)
- fPageAreas.theMargins = VRect(IntMultiply((short)fPageAreas.theMargins.top, fMarginRes.v) / oldMarginRes.v, IntMultiply((short)fPageAreas.theMargins.left, fMarginRes.h) / oldMarginRes.h, IntMultiply((short)fPageAreas.theMargins.bottom, fMarginRes.v) / oldMarginRes.v, IntMultiply((short)fPageAreas.theMargins.right, fMarginRes.h) / oldMarginRes.h);
-
- aRect = fPageAreas.thePaper;
- bRect = fPageAreas.theInk;
- if ((aRect != oldPageAreas.thePaper) || (bRect != oldPageAreas.theInk) || (fDeviceRes != oldDevRes) || (oldPrinterDev == kNeverInitialized))
- {
- msgSent = FALSE; // something important to our projection model changed...
- if (fDocument)
- if (fDocument->fSharePrintInfo)
- {
- fDocument->ForAllViewsDo(ItChanged, this);
- msgSent = TRUE;
- }
-
- if (!msgSent) // didn't send msg to all views, current company included,
- // so now we need to tell must my local view
- fView->DoPrinterChanged();
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintImage
-
- pascal void TStdPrintHandler::ChooseSpoolFile(Str255& spoolFileName,
- short& spoolVRefNum,
- long& pagesPerSubjob)
- {
- spoolFileName = ""; // Default choices tell MacPrint to use its
- // standard choice algorithm
- spoolVRefNum = 0;
-
- // Print Shop suggests attempting to print entire document. If it
- // runs out of space, then PerformPrinting will retry with a
- // smaller number of pages.
- pagesPerSubjob = MAXINT;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::ClosePrintShop(void)
- {
- #if qDebug
- OSErr err;
- #endif
-
- PrClose();
- #if qDebug
- err = PrError(); // Now check for fresh error from MacPrint --
- // only for debugging, since ChkPrintErr
- // checks afresh in the real world
- if (err != noErr)
- cout << form("Error from MacPrint is: %1d\n", err);
- #endif
-
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::DoInMacPrint(pascal void(* WhatToDo)(void* staticLink),
- void* staticLink)
- {
- FailInfo fi;
-
- if (gCouldPrint)
- {
- PrSetError(noErr); // Clear printer-error flag
- if (!fi.CatchFailure())
- {
- this->OpenPrintShop();
- (*WhatToDo)(staticLink); // Do what needs to be done
- fi.Success();
- }
- else
- {
- this->ClosePrintShop();
- SetPort(gWorkPort); // Might be left looking at a dead port
- gApplication->InvalidateFocus();
- fi.ReSignal();
- }
- this->ClosePrintShop();
- SetPort(gWorkPort); // Might be left looking at a dead port
- gApplication->InvalidateFocus();
- }
- // NB: if gCouldPrint is FALSE, DoInMacPrint is a no-op
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintSelCommand
-
- pascal void TStdPrintHandler::DoMenuCommand(CmdNumber aCmdNumber)// override
- {
- Boolean proceed;
- TPrintCommand * aPrintCommand;
-
- switch (aCmdNumber)
- {
- case cPrint:
- this->CheckPrinter();
- if (this->PoseJobDialog())
- {
- aPrintCommand = new TPrintCommand;
- aPrintCommand->IPrintCommand(aCmdNumber, this);
- this->PostCommand(aPrintCommand);
- }
- break;
-
- case cPrintOne:
- this->CheckPrinter();
- if (this->SetupPrintOne())
- {
- aPrintCommand = new TPrintCommand;
- aPrintCommand->IPrintCommand(aCmdNumber, this);
- this->PostCommand(aPrintCommand);
- }
- break;
-
- case cPageSetup:
- this->PosePageSetupDialog(proceed, TRUE);
- break;
-
- case cShowBreaks: // Toggle state of "Show Breaks"
- fShowBreaks =!fShowBreaks;
- this->InvalPageFeedback(); // force redraw of area the breaks did or will occupy
- break;
-
- default:
- inherited::DoMenuCommand(aCmdNumber);
- break;
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::DoSetupMenus(void)// override
- {
- inherited::DoSetupMenus();
-
- if (gCouldPrint && fView &&!MemSpaceIsLow())
- {
- Enable(cPrint, TRUE);
- Enable(cPageSetup, TRUE);
- Enable(cPrintOne, TRUE);
- }
-
- EnableCheck(cShowBreaks, TRUE, fShowBreaks);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
- // A local class to help iterate over the list of handles and insert into a DescList
-
- class CPageBreaks
- {
- VHSelect& fOrthoVHS;
- VHSelect& fVHS;
- short& fWhichBreak;
- const VRect& fViewArea;
- TView* fView;
-
- public:
- CPageBreaks(VHSelect& theOrthoVHS,
- VHSelect& theVHS,
- short& whichBreak,
- const VRect& theViewArea,
- TView* theView) :
- fOrthoVHS(theOrthoVHS),
- fVHS(theVHS),
- fWhichBreak(whichBreak),
- fViewArea(theViewArea),
- fView(theView)
- {
- }
-
- pascal Boolean DrawABreak(VCoordinate loc,
- Boolean automatic);
- };
-
- #pragma segment PrintRes
- pascal Boolean CPageBreaks::DrawABreak(VCoordinate loc,
- Boolean automatic)
- {
- if (loc > fViewArea[botRight][fOrthoVHS])
- return TRUE;
- else
- {
- ++fWhichBreak;
- if (loc > (fViewArea[topLeft][fOrthoVHS] - Point(gBreaksPenState.pnSize)[fOrthoVHS]))
- fView->DoDrawPageBreak(fVHS, fWhichBreak, loc, automatic);
- return FALSE;
- }
- }
-
- #pragma segment PrintRes
- // Draws page breaks and page numbers
- pascal void TStdPrintHandler::DrawPrintFeedback(const VRect& area)// override
- {
- if (qDebug)
- fView->AssumeFocused();
- if (fShowBreaks || gDebugPrinting)
- {
- VHSelect vhs;
- VHSelect orthoVHS;
- short whichBreak = 0;
- CPageBreaks aPageBreak(orthoVHS, vhs, whichBreak, area, fView);
-
- this->SetPrintExtent(); // Make sure print extent is accurate before starting
- #if qDebug
- if (gDebugPrinting) // Now draw Page numbers in the corners of pages, if desired
- {
- TextStyle pageNumStyle;
-
- SetTextStyle(pageNumStyle, applFont, bold, 9, gRGBBlack);
- SetPortTextStyle(pageNumStyle);
- }
- #endif
-
- SetPenState(gBreaksPenState);
-
- for (vhs = vSel; vhs <= hSel; ++vhs)
- {
- orthoVHS = gOrthogonal[vhs];
- whichBreak = 0;
- this->EachBreak(vhs, FALSE, (DoToBreakType) & CPageBreaks::DrawABreak, &aPageBreak);
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- #if qDebug
- pascal void TStdPrintHandler::DrawPageBreak(VHSelect vhs,
- long whichBreak,
- VCoordinate loc,
- Boolean)// override
- #else
- pascal void TStdPrintHandler::DrawPageBreak(VHSelect vhs,
- long/* whichBreak */,
- VCoordinate loc,
- Boolean)// multiple declarations to eliminate compiler warnings
- #endif
-
- {
- VPoint vPt;
- Point qdStartPt;
- Point qdEndPt;
-
- vPt[gOrthogonal[vhs]] = loc;
- vPt[vhs] = 0;
- qdStartPt = fView->ViewToQDPt(vPt);
- vPt[vhs] = fView->fSize[vhs] - Point(gBreaksPenState.pnSize)[vhs];
- qdEndPt = fView->ViewToQDPt(vPt);
-
- if (fShowBreaks)
- {
- MoveTo(qdStartPt.h, qdStartPt.v);
- LineTo(qdEndPt.h, qdEndPt.v);
- }
-
- #if qDebug
- if (gDebugPrinting)
- if (vhs == hSel)
- {
- VCoordinate hLoc;
- Str255 aString;
- FontInfo theFontInfo;
- Rect theTextRect;
-
- for (long i = 0; i <= fPageStrips.v; ++i)
- {
- if (i == 0)
- hLoc = 0;
- else
- this->GetBreakCoord(vSel, i, hLoc);
-
- GetFontInfo(theFontInfo);
-
- NumToString(this->StripToPage(whichBreak - 1, i), aString);
- // top computed based on the bottom - text height
- theTextRect = Rect(qdStartPt.v - 3 - theFontInfo.ascent, (short)hLoc + 3, qdStartPt.v - 3 + theFontInfo.descent, (short)hLoc + 3 + StringWidth(aString));
- MADrawString(aString, theTextRect, teFlushDefault);
-
- NumToString(this->StripToPage(whichBreak, i), aString);
- // top computed based on the bottom - text height
- theTextRect = Rect(qdEndPt.v + 10 - theFontInfo.ascent, (short)hLoc + 3, qdEndPt.v + 10 + theFontInfo.descent, (short)hLoc + 3 + StringWidth(aString));
- MADrawString(aString, theTextRect, teFlushDefault);
-
- NumToString(this->StripToPage(whichBreak - 1, i - 1), aString);
- // top computed based on the bottom - text height
- theTextRect = Rect(qdStartPt.v - 3 - theFontInfo.ascent, (short)hLoc - StringWidth(aString) - 3, qdStartPt.v - 3 + theFontInfo.descent, (short)hLoc - 3);
- MADrawString(aString, theTextRect, teFlushDefault);
-
- NumToString(this->StripToPage(whichBreak, i - 1), aString);
- // top computed based on the bottom - text height
- theTextRect = Rect(qdEndPt.v + 10 - theFontInfo.ascent, (short)hLoc - StringWidth(aString) - 3, qdEndPt.v + 10 + theFontInfo.descent, (short)hLoc - 3);
- MADrawString(aString, theTextRect, teFlushDefault);
- }
- }
- #endif
-
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintImage
-
- pascal void TStdPrintHandler::DrawPageInterior(void)
- {
- fView->DrawContents(); // i.e., by default, the same code used for drawing on the screen
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::EachBreak(VHSelect vhs,
- Boolean includeLast,
- pascal Boolean(* DoToBreak)(VCoordinate loc,
- Boolean automatic,
- void* staticLink),
- void* staticLink)
- {
- VCoordinate startLoc;
- VCoordinate endLoc;
- VCoordinate loc;
- Boolean automatic;
- Boolean done;
- VCoordinate prevBreak = 0;
-
- startLoc = fPrintExtent[topLeft][gOrthogonal[vhs]];
- endLoc = fPrintExtent[botRight][gOrthogonal[vhs]];
-
- loc = startLoc;
- automatic = TRUE;
- done = FALSE;
- while ((loc < endLoc) &&!done)
- {
- if (loc != startLoc)
- done = (*DoToBreak)(loc, automatic, staticLink);
- if (qDebug)
- prevBreak = loc;
-
- loc = fView->DoBreakFollowing(vhs, loc, automatic);
-
- if (qDebug && (loc <= prevBreak))
- ProgramBreak("thisBreak (loc) <= prevBreak");// Thanks much to Larry T. !
- }
-
- if (includeLast)
- (*DoToBreak)(loc, automatic, staticLink);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintFields
-
- pascal void TStdPrintHandler::Fields(TObject* obj)
- {
- obj->DoToField("TStdPrintHandler", NULL, bClass);
- obj->DoToField("fPageAreas", NULL, bTitle);
- obj->DoToField(" thePaper", &fPageAreas.thePaper, bRect);
- obj->DoToField(" theInk", &fPageAreas.theInk, bRect);
- obj->DoToField(" theMargins", &fPageAreas.theMargins, bRect);
- obj->DoToField(" theInterior", &fPageAreas.theInterior, bRect);
- obj->DoToField("fPrintExtent", &fPrintExtent, bVRect);
- obj->DoToField("fFixedSizePages[h]", &fFixedSizePages[hSel], bBoolean);
- obj->DoToField("fFixedSizePages[v]", &fFixedSizePages[vSel], bBoolean);
- obj->DoToField("fHPrint", &fHPrint, bHandle);
- obj->DoToField("fPageStrips", &fPageStrips, bPoint);
- obj->DoToField("fStartPage", &fStartPage, bLongInt);
- obj->DoToField("fPrinterDev", &fPrinterDev, bLongInt);
- obj->DoToField("fLastPrinterName", &fLastPrinterName, bStringHandle);
- obj->DoToField("fPageDirection", &fPageDirection, bVHSelect);
- obj->DoToField("fShowBreaks", &fShowBreaks, bBoolean);
- obj->DoToField("fFinderSetup", &fFinderSetup, bBoolean);
- obj->DoToField("fFinderJobDialog", &fFinderJobDialog, bBoolean);
- obj->DoToField("fSquareDots", &fSquareDots, bBoolean);
- obj->DoToField("fMinimalMargins", &fMinimalMargins, bBoolean);
- obj->DoToField("fLastStrip", &fLastStrip, bPoint);
- obj->DoToField("fLastBreak", &fLastBreak, bVPoint);
- obj->DoToField("fViewedRect", &fViewedRect, bVRect);
- obj->DoToField("fMarginRes", &fMarginRes, bPoint);
- obj->DoToField("fPrintDialog", &fPrintDialog, bWindowPtr);// need a bDialogPtr
-
- obj->DoToField("fPPrPort", NULL, bTitle);
- if (fPPrPort)
- {
- obj->DoToField(" gPort", &fPPrPort, bGrafPtr);
- obj->DoToField(" gProcs", &fPPrPort->gProcs, bQDProcs);
- obj->DoToField(" IGParam1", &fPPrPort->lGParam1, bLongInt);
- obj->DoToField(" IGParam2", &fPPrPort->lGParam2, bLongInt);
- obj->DoToField(" IGParam3", &fPPrPort->lGParam3, bLongInt);
- obj->DoToField(" IGParam4", &fPPrPort->lGParam4, bLongInt);
- obj->DoToField(" fOurPtr", &fPPrPort->fOurPtr, bBoolean);
- obj->DoToField(" fOurBits", &fPPrPort->fOurBits, bBoolean);
- }
- inherited::Fields(obj);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintImage
-
- pascal void TStdPrintHandler::FocusOnBorder(void)
- {
- VRect rectToClipTo(fPageAreas.theInk);
- Rect qdRectToClipTo;
-
- // Only works for newer LaserWriter drivers
- SetOrigin((short)fPageAreas.theInk.left, (short)fPageAreas.theInk.top);
- fView->ViewToQDRect(rectToClipTo, qdRectToClipTo);
- ClipRect(qdRectToClipTo);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintImage
-
- pascal void TStdPrintHandler::FocusOnInterior(void)// override
- {
- VRect rectToClip;
- VRect aRect;
- VPoint theOrigin;
- VPoint theVOrigin;
- VRect aVRect;
- Rect qdRectToClip;
-
- aRect = fPageAreas.theInk;
- theOrigin = fPageAreas.theInk[topLeft];
- for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
- if (fView->fSize[vhs] > kMaxCoord)
- theVOrigin[vhs] = gPageOffset[vhs];
- else
- {
- theVOrigin[vhs] = 0;
- theOrigin[vhs] = theOrigin[vhs] + gPageOffset[vhs];
- aRect[topLeft][vhs] = aRect[topLeft][vhs] + gPageOffset[vhs];
- aRect[botRight][vhs] = aRect[botRight][vhs] + gPageOffset[vhs];
- }
- SetOrigin((short)theOrigin.h, (short)theOrigin.v);
- fView->fViewToQDOffset = theVOrigin;
-
- // Clip the page to the intersection of the visible part of the view and the
- // printable area of the page. Note that in some cases (e.g., a WYSIWYG
- // word processor which showed the complete page margin) parts of
- // the interior might lie outside theInk. We must clip to theInk to
- // avoid slowing down PostScript printers.
- rectToClip = fViewedRect;
- SectVRect(rectToClip, aRect, rectToClip);
- fView->ViewToQDRect(rectToClip, qdRectToClip);
- ClipRect(qdRectToClip);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::GetBreakCoord(VHSelect vhs,
- long whichBreak,
- VCoordinate& loc)
- {
- Boolean automatic;
- long startBreak;
- VHSelect orthoVHS;
- VCoordinate prevBreak = 0;
-
-
- orthoVHS = gOrthogonal[vhs];
- if (fFixedSizePages[orthoVHS])
- loc = fPrintExtent[topLeft][orthoVHS] + fViewPerPage[orthoVHS] * whichBreak;
- else if (whichBreak == fLastStrip[vhs])
- loc = fLastBreak[vhs];
- else
- {
- if (whichBreak > fLastStrip[vhs])
- {
- startBreak = fLastStrip[vhs] + 1;
- loc = fLastBreak[vhs];
- }
- else
- {
- startBreak = 1;
- loc = fPrintExtent[topLeft][gOrthogonal[vhs]];
- }
-
- for (long i = startBreak; i <= whichBreak; ++i)
- {
- if (qDebug)
- prevBreak = loc;
-
- loc = fView->DoBreakFollowing(vhs, loc, automatic);// ??? error handling???
-
- if (qDebug && (loc <= prevBreak))
- ProgramBreak("thisBreak (loc) <= prevBreak");
- }
- }
- loc = Min(loc, fPrintExtent[botRight][orthoVHS]);
-
- fLastStrip[vhs] = whichBreak;
- fLastBreak[vhs] = loc;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
-
- pascal void TStdPrintHandler::GetDocName(Str255& docName)
- {
- TView * aView;
-
- if (fDocument)
- fDocument->GetTitle(docName);
- if (docName.IsEmpty())
- {
- aView = fView->GetRootView();
- if (aView && aView->IsMemberClass(GetClassIDFromName("TWindow")))
- ((TWindow *)aView)->GetTitle(docName);
- }
- #if qDebug
- if (docName.IsEmpty())
- ProgramBreak("GetDocName can''t get a document or window name");
- #endif
-
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintMain
-
- pascal Handle TStdPrintHandler::GetPrintInfo(void)
- {
- return fHPrint;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void TStdPrintHandler::InstallMargins(const VRect& newMargins,
- Boolean areMinimalMargins)
- {
- fMinimalMargins = areMinimalMargins;
-
- if (fMinimalMargins)
- {
- fPageAreas.theMargins = fPageAreas.theInk;
- fPageAreas.thePaper[topLeft] -= fPageAreas.theMargins[topLeft];
- fPageAreas.thePaper[botRight] -= fPageAreas.theMargins[botRight];
- fPageAreas.theInterior = fPageAreas.theInk;
- }
- else
- {
- fPageAreas.theMargins = newMargins;
- fPageAreas.theInterior = fPageAreas.thePaper;
- fPageAreas.theMargins[topLeft] += fPageAreas.theInterior[topLeft];
- fPageAreas.theMargins[botRight] += fPageAreas.theInterior[botRight];
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void TStdPrintHandler::InvalPageFeedback(void)
- {
- if (this->ShowsOnScreen())
- fView->ForceRedraw();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void TStdPrintHandler::LocatePageInterior(long,
- VPoint& loc)// override
- {
- loc = fPageAreas.thePaper[topLeft];
- fPageAreas.theMargins[topLeft] += loc;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
-
- pascal long TStdPrintHandler::MaxPageNumber(void)// override
-
- {
- return fStartPage + (fPageStrips.v * fPageStrips.h) - 1;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
-
- pascal void TStdPrintHandler::OneSubJob(long subjobFirstPage,
- long subjobLastPage,
- Boolean justSpool,
- Boolean,
- Boolean& ranOutOfSpace,
- long& lastPageTried,
- Boolean& proceed)
- {
- long noOfCopies;
- OSErr err;
- TPrJob & printJob = ((TPPrint) * fHPrint)->prJob;
- FailInfo fi;
-
- #if qDebug
- if (gDebugPrinting)
- cout << form("OneSubJob entered for pages %1d through %1d, proceed=", subjobFirstPage, subjobLastPage) << proceed << "\n";
- #endif
-
- ranOutOfSpace = FALSE;
- lastPageTried = subjobFirstPage - 1;
-
- printJob.iFstPage = 1;
- printJob.iLstPage = (short)(subjobLastPage - subjobFirstPage + 1);
-
- if (printJob.bJDocLoop == bSpoolLoop)
- noOfCopies = 1;
- else
- noOfCopies = printJob.iCopies;
-
- fPPrPort = PrOpenDoc((THPrint)fHPrint, NULL, NULL);
- // ??? need to allow/encourage app to supply nonNil args?
- this->ChkPrintErr(err, proceed, ranOutOfSpace);
- gCurrPrintHandler = this;
-
- if (proceed)
- {
- fView->InvalidateFocus();
- fView->UpdateCoordinates();
- gPrinting = TRUE;
- SetPort((GrafPtr)fPPrPort);
- fView->BeInPort((GrafPtr)fPPrPort);
-
- gPrinting = TRUE;
- if (!fView->Focus())
- {
- #if qDebug
- ProgramBreak("Can''t focus view while printing");
- #endif
-
- }
- for (long pass = 1; pass <= noOfCopies; ++pass)
- for (long aPageNumber = subjobFirstPage; aPageNumber <= subjobLastPage; ++aPageNumber)
- if (proceed)
- {
- lastPageTried = aPageNumber;
- if (!fi.CatchFailure())
- {
- this->PrintPage(aPageNumber);
- fi.Success();
- }
- else
- {
- proceed = FALSE;
- err = fi.error; // pass along client's error code Why???
- }
- this->ChkPrintErr(err, proceed, ranOutOfSpace);
- }
- gPrinting = FALSE;
- fView->InvalidateFocus();
- fView->UpdateCoordinates();
- fView->BeInPort(fView->GetGrafPort());
- }
-
- gCurrPrintHandler = NULL;
- PrCloseDoc(fPPrPort); // This will close the port!
- SetPort(gWorkPort);
- this->ChkPrintErr(err, proceed, ranOutOfSpace);
-
- if (ranOutOfSpace)
- return;
- else if (proceed)
- {
- if (printJob.bJDocLoop == bSpoolLoop)
- if (!justSpool)
- this->PrintSpoolFile(fHPrint, err, proceed);
- }
- if (!proceed)
- if (err != iPrAbort)
- Failure(err, 0);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::OpenPrintShop(void)
- {
- OSErr err;
-
- PrOpen(); // Open the print shop
- err = PrError(); // Get code
- if (err != noErr)
- {
- if ((err == fnfErr) || (err == resFNotFound))
- err = errNoPrintDrvr;
- Failure(err, 0);
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal VPoint TStdPrintHandler::PageToStrip(long pageNumber)
- {
- long normalizedPageNum;
- VHSelect ortho;
- VPoint strip;
-
- normalizedPageNum = pageNumber - fStartPage + 1;
-
- ortho = gOrthogonal[fPageDirection];
-
- strip[ortho] = (normalizedPageNum - 1) / fPageStrips[ortho];
- strip[fPageDirection] = normalizedPageNum - ((strip[ortho]) * fPageStrips[ortho]) - 1;
-
- return strip;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- // !!! Need to test this!
- pascal VPoint TStdPrintHandler::PointToPageStrip(const VPoint& pointInView)
- {
- long loc;
- Boolean automatic;
- VPoint pageStrip;
- VCoordinate prevBreak = 0;
-
-
- for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
- if (fFixedSizePages[vhs])
- pageStrip[vhs] = (pointInView[vhs] / fViewPerPage[vhs]) + 1;
- else
- {
- pageStrip[vhs] = 1;
- loc = fPrintExtent[topLeft][vhs]; // ??? or orthogonal?
- while (pointInView[vhs] > loc)
- // ??? or orthogonal?
- {
- if (qDebug)
- prevBreak = loc;
-
- loc = fView->DoBreakFollowing(vhs, loc, automatic);
-
- if (qDebug && (loc <= prevBreak))
- ProgramBreak("thisBreak (loc) <= prevBreak");
-
- pageStrip[vhs]++; // ??? Check the pascal. This may be wrong. !!!
- }
- }
- return pageStrip;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
-
- class CPrintDialogs
- {
- Boolean& fResult;
- Handle& fHPrint;
-
- public:
- CPrintDialogs(Boolean& proceed,
- Handle& printHandle) :
- fResult(proceed),
- fHPrint(printHandle)
- {
- }
-
- pascal void CallJobDialog(void);
-
- pascal void CallStyleDialog(void);
-
- pascal void CallPrValidate(void);
- };
-
- #pragma segment PrintActual
- pascal void CPrintDialogs::CallJobDialog(void)
- {
- SetCursor(qd.arrow);
- if (gApplication)
- gApplication->InvalidateMouseRegions();
-
- fResult = PrJobDialog((THPrint)fHPrint);
- }
-
- #pragma segment PrintActual
- pascal void CPrintDialogs::CallStyleDialog(void)
- {
- SetCursor(qd.arrow);
- if (gApplication != NULL)
- gApplication->InvalidateMouseRegions();
-
- fResult = PrStlDialog((THPrint)fHPrint);
- }
-
- #pragma segment PrintActual
- pascal void CPrintDialogs::CallPrValidate(void)
- {
- fResult = PrValidate((THPrint)fHPrint);
- }
-
- #pragma segment PrintActual
- pascal Boolean TStdPrintHandler::PoseJobDialog(void)
- {
- Boolean b;
- Boolean proceed;
- OSErr err;
- TPrJob & printJob = ((TPPrint) * fHPrint)->prJob;
- CPrintDialogs aJobDialog(proceed, fHPrint);
-
- proceed = TRUE;
- // PrepareForDialog;
- this->DoInMacPrint((WhatToDoType) & CPrintDialogs::CallJobDialog, &aJobDialog);
- this->ChkPrintErr(err, proceed, b);
- // Rectify the range as a public service if needed
- if (printJob.iFstPage > printJob.iLstPage)
- {
- short temp;
-
- temp = printJob.iLstPage;
- printJob.iLstPage = printJob.iFstPage;
- printJob.iFstPage = temp;
- }
- gApplication->UpdateAllWindows();
- return proceed;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
- // Needs to be here because it may be called from Print
-
- pascal void TStdPrintHandler::PosePageSetupDialog(Boolean& proceed,
- Boolean isUndoable)
- {
- Boolean react;
- TPrintStyleChangeCommand * aPrintStyleChangeCommand;
- CPrintDialogs aPageSetupDialog(react, fHPrint);
-
- react = FALSE; // in case MacPrint code not accessible
- if (!isUndoable)
- {
- // PrepareForDialog;
- this->DoInMacPrint((WhatToDoType) & CPrintDialogs::CallStyleDialog, &aPageSetupDialog);
- if (react)
- this->CheckPrinter();
- }
- else
- {
- // Must setup command before putting up page setup dialog because the
- // command records the current print record to make it undoable.
- aPrintStyleChangeCommand = new TPrintStyleChangeCommand;
- aPrintStyleChangeCommand->IPrintStyleChangeCommand(this);
-
- // Put up the Page Setup Dialog
- this->DoInMacPrint((WhatToDoType) & CPrintDialogs::CallStyleDialog, &aPageSetupDialog);
- if (react) // User specified a change
- {
- BlockMove((Ptr) * fHPrint, (Ptr) * (aPrintStyleChangeCommand->fNewHPrint), sizeof(TPrint));
- this->PostCommand(aPrintStyleChangeCommand);
- }
- else // User did not specify a change
- aPrintStyleChangeCommand = (TPrintStyleChangeCommand *)FreeIfObject(aPrintStyleChangeCommand);
- }
- proceed = react;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintActual
-
- pascal void TStdPrintHandler::PosePrintDialog(void)
- {
- short dlgNumber;
- DialogTHndl dlogTemplate;
- Str255 docName;
- short itemNo;
- Handle theItem;
- short itemType;
- Rect box;
- Str255 itemText;
- short preDocName,
- constTitle;
-
- /*### need to determine if multiple file printing is in process
- if (gFinderPrinting)
- {
- dlgNumber = phFinderPrintDialog;
- itemNo = 3;
- }
- else
- {
- dlgNumber = phSpoolPrintDialog;
- itemNo = 2;
- }
- */
- dlgNumber = phSpoolPrintDialog;
- itemNo = 2;
-
- // Can't use GetNewCenteredDialog because vertically centering the dialog may cause it
- // to interfere with the Print Manager's status windows. Therefore, leave the vertical
- // location of the dialog fixed.
-
- SetCursor(qd.arrow);
- gApplication->InvalidateMouseRegions();
- dlogTemplate = (DialogTHndl)GetResource('DLOG', dlgNumber);
- if (dlogTemplate)
- {
- CenterRectOnScreen((*dlogTemplate)->boundsRect, TRUE, FALSE, FALSE);
- fPrintDialog = GetNewDialog(dlgNumber, (Ptr)NULL, (WindowPtr) - 1);
- FailNIL(fPrintDialog);
- }
- else
- {
- #if qDebug
- cout << "You may have forgotten to include Printing.rsrc in your .r file…\n";
- ProgramBreak("The print job dialog resource can''t be found.");
- #endif
-
- FailNILResource((Handle)dlogTemplate);
- }
-
- // Substitute the document name for '<<!=>>' in 'Document “<<!=>>” is being printed'.
- // ParamText would be a lot simpler, but the Print Mgr. also uses ParamText, and
- // the substitution doesn't happen until draw time.
- this->GetDocName(docName);
- GetDItem(fPrintDialog, itemNo, itemType, theItem, box);
- if (theItem)
- {
- GetIText(theItem, itemText);
- if (ParseTitleTemplate(itemText, preDocName, constTitle) && SubstituteInTitle(itemText, docName, preDocName, constTitle))
- SetIText(theItem, itemText);
- }
-
- ((TPPrint) * fHPrint)->prJob.pIdleProc = &IdleProcForTStdPrintHandler;
- SetWTitle(fPrintDialog, docName); // In case Print Mgr. needs it.
- DrawDialog(fPrintDialog);
- }
-
- //--------------------------------------------------------------------------------------------------
- // ???Was in PrintActual. Doesn't really belong in this segment,
- //but can get unloaded during Finder printing otherwise.
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::Print(CmdNumber itsCmdNumber,
- Boolean& proceed)// override
- {
- FailInfo fi;
-
- gCancelAllPrinting = FALSE;
-
- this->SetPrintExtent(); // Make sure we've got the right area.
-
- if (!fi.CatchFailure())
- {
- if (gCouldPrint)
- {
- long firstPage;
- long lastPage;
- OSErr err;
- Str255 spoolFileName;
- short spoolVRefNum;
- TPrJob aPrJob = ((TPPrint) * fHPrint)->prJob;
- long totalPages;
- long lastPrinted;
- long lastAttempted;
- long pagesPerSubjob;
- long firstSubjobPage;
- Boolean proceed = TRUE;
- Boolean ranOutOfSpace = FALSE;
- Boolean spoolMethod;
- Boolean justSpool = (itsCmdNumber == cPrintToFile);
- VPoint pageStrips;
- FailInfo fi;
-
- PrSetError(noErr); // Clear printer-error flag
- this->OpenPrintShop();
- gJobPrintHandler = this; // be visible to the idleProc
- fView->DoCalcPageStrips(pageStrips);
- fPageStrips = pageStrips;
-
- firstPage = Max(aPrJob.iFstPage, fStartPage);
- lastPage = Min(aPrJob.iLstPage, this->MaxPageNumber());
-
- if (lastPage < firstPage)
- err = Alert(phNoPages, NULL);
- else
- {
- totalPages = lastPage - firstPage + 1;
- spoolMethod = (aPrJob.bJDocLoop == bSpoolLoop);
- if (spoolMethod)
- {
- this->ChooseSpoolFile(spoolFileName, spoolVRefNum, pagesPerSubjob);
- // if justSpool is true, then the spool filename and vRefNum will already
- // have been stuffed into the prJob record before this method is called
- if (!justSpool)
- {
- if (!spoolFileName.IsEmpty())
- {
- aPrJob.pFileName = &spoolFileName;
- aPrJob.iFileVol = spoolVRefNum;
- }
- }
- }
- else
- pagesPerSubjob = MAXINT;
-
- lastPrinted = firstPage - 1;
-
- pagesPerSubjob = Min(pagesPerSubjob, totalPages);
- this->PosePrintDialog();
-
- if (!fi.CatchFailure())
- {
- do
- {
- firstSubjobPage = lastPrinted + 1;
- this->OneSubJob(firstSubjobPage, firstSubjobPage + pagesPerSubjob - 1, justSpool, (pagesPerSubjob < totalPages), ranOutOfSpace, lastAttempted, proceed);
- if (proceed)
- lastPrinted = lastAttempted;
- if (ranOutOfSpace)
- {
- pagesPerSubjob = lastAttempted - 1 - firstSubjobPage;
- proceed = TRUE;
- }
- } while ((lastPrinted == lastPage) || (pagesPerSubjob < 1) ||!proceed);
-
- if (pagesPerSubjob < 1)
- Failure(errSpooling, 0);
- fi.Success();
- }
- else
- {
- this->BanishPrintDialog();
- fi.ReSignal();
- }
- this->BanishPrintDialog(); // having removed, put back here, unsure if exactly right
- } // if there are pages within requested range
- gJobPrintHandler = NULL; // out damned spot
- }
- this->ClosePrintShop();
- SetPort(gWorkPort); // Might be left looking at a dead port
- gApplication->InvalidateFocus();
- fi.Success();
- }
- else
- {
- this->ClosePrintShop();
- SetPort(gWorkPort); // Might be left looking at a dead port
- gApplication->InvalidateFocus();
-
- // Certain Print Manager errors should not result in any alert,
- // since the Print Manager will have already put one up.
- if ((fi.error >= -8160) && (fi.error <= -8150))
- Failure(0, msgPrintFailed);
- if (fi.message == 0)
- this->GetDocName(gErrorParm3);
- FailNewMessage(fi.error, fi.message, msgPrintFailed);
- fi.ReSignal();
- }
- proceed =!gCancelAllPrinting;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void TStdPrintHandler::PrinterChanged(void)// override
- {
- fView->DoPagination();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintImage
-
- pascal void TStdPrintHandler::PrintPage(long aPageNumber)// Print a single page
- {
- FailInfo fi;
-
- this->SetPage(aPageNumber); // gets gPage set up correctly for coordinate transformations
- if (!fi.CatchFailure())
- {
- #if qDebug
- GrafPtr aPort;
- #endif
-
- PrOpenPage(fPPrPort, NULL);
- FailOSErr(PrError());
- this->FocusOnInterior();
- this->DrawPageInterior();
- #if qDebug
- GetPort(aPort);
- if (aPort != ((GrafPtr) fPPrPort))
- ProgramBreak("The view''s DrawPageInterior method changed the grafPort");
- #endif
-
- FailOSErr(PrError());
- this->FocusOnBorder();
- this->AdornPage();
- FailOSErr(PrError());
- fi.Success();
- }
- else
- {
- PrClosePage(fPPrPort);
- fi.ReSignal();
- }
- PrClosePage(fPPrPort);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- // Called from fView.DoPagination.
- pascal void TStdPrintHandler::RedoPageBreaks(void)// override
- {
- Boolean worryAboutBreaks;
- VPoint oldViewPerPage, viewPerPage;
- VPoint pageStrips;
- VRect newInterior, oldInterior;
-
- worryAboutBreaks = (fView->GetGrafPort()) && gInitialized && (fShowBreaks || gDebugPrinting);
-
- if (worryAboutBreaks)
- this->InvalPageFeedback(); // invalidate old page breaks, if relevant
-
- this->SetPrintExtent();
- oldInterior = fPageAreas.theInterior;
- oldViewPerPage = fViewPerPage;
- this->SetMargins();
-
- // computes view per page from papersize, printer resolution, margins desired, view resolution,
- //and, if desired, other factors such as printable rectangle of page and font metrics in the
- //printer space
- fView->DoCalcViewPerPage(viewPerPage);
- fViewPerPage = viewPerPage;
- this->SetPageInterior(kUsualPages);
- newInterior = fPageAreas.theInterior;
-
- #if qDebug
- if (gDebugPrinting)
- if (oldInterior != newInterior)
- ProgramBreak("Setting new interior");
- #endif
-
- if (oldInterior != newInterior)
- fView->PageInteriorChanged(newInterior);
-
- #if qDebug
- if (gDebugPrinting)
- if (oldViewPerPage != viewPerPage)
- ProgramBreak("Setting new view per page");
- #endif
-
- if ((oldInterior != newInterior) || (oldViewPerPage != viewPerPage))
- fView->AdjustSize();
-
- fView->DoCalcPageStrips(pageStrips);
- fPageStrips = pageStrips;
-
- if (worryAboutBreaks)
- this->InvalPageFeedback(); // force redraw of new page breaks, if relevant
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void CallPrintDefault(void* staticLink)
- {
- PrintDefault(*((THPrint *)staticLink));
- }
-
-
- pascal void TStdPrintHandler::Reset(void)
- {
- THPrint anHPrint = (THPrint)fHPrint;
- Boolean didChange;
- Boolean inited = FALSE;
- FailInfo fi;
-
- if (anHPrint)
- {
- if (gCouldPrint)
- {
- if (!fi.CatchFailure())
- {
- TXWord printerFlags;
-
- this->DoInMacPrint(CallPrintDefault, &anHPrint);
- if (fSquareDots)
- {
- printerFlags.iO = ((TPPrint) * fHPrint)->prStl.wDev;
- if (printerFlags.byteVal.b1 == 1)// 1 == bDevCItoh => ImageWriter
- {
- // Set the square-pixel flag in the print record, then
- // ensure we didn't corrupt it.
- printerFlags.boolVal.f2 = TRUE;
- this->ValidatePrintRecord(didChange);
- }
- }
- inited = TRUE;
- fi.Success();
- }
- }
- // MacPrint code unavailable, but we want some plausible things
- // anyway - set up for Portrait Tall Adj.
- // ??? Replace the following expensive stuffing code with StuffHex
- // calls or a GetResource or some such, later
- if (!(gCouldPrint && inited))
- {
- (*anHPrint)->iPrVersion = 0; // something invalid
-
- (*anHPrint)->prInfo.iHRes = 72;
- (*anHPrint)->prInfo.iVRes = 72;
- (*anHPrint)->prInfo.rPage = Rect(0, 0, 752, 576);// must have its top left & (0,0)
-
- (*anHPrint)->rPaper = Rect(-36, -18, 756, 594);
- (*anHPrint)->prStl.iPageV = 1320;// 11 inches in 120th of an inch
- (*anHPrint)->prStl.iPageH = 1020;// 8.5 inches in 120th of an inch
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void TStdPrintHandler::SetPrintExtent(void)
- {
- VRect printExtent;
-
- fView->GetPrintExtent(printExtent);
- // Make sure the bottom or right is not smaller than the top or left.
- // This can happen when views are being created and before the window
- // has been resized to its actual size.
- printExtent.bottom = Max(printExtent.bottom, printExtent.top);
- printExtent.right = Max(printExtent.right, printExtent.left);
- fPrintExtent = printExtent;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintOpen
-
- pascal void TStdPrintHandler::SetDefaultPrintInfo(void)
- {
- Boolean didChange;
- Boolean wantValidate = FALSE;
- Boolean haveHPrint = FALSE;
-
- fHPrint = DisposeIfHandle(fHPrint);
-
- if (fView)
- {
- if (fDocument && (fDocument->fSharePrintInfo && fDocument->fPrintInfo))
- {
- fHPrint = fDocument->fPrintInfo;
- haveHPrint = TRUE;
- }
- }
-
- if (haveHPrint)
- wantValidate = TRUE;
- else
- {
- fHPrint = NewPermHandle(sizeof(TPrint));
- this->Reset();
- }
-
- if (wantValidate)
- this->ValidatePrintRecord(didChange);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void TStdPrintHandler::SetMargins(void)
- {
- VRect someMargins;
-
- someMargins = fPageAreas.theMargins;
- this->InstallMargins(someMargins, fMinimalMargins);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintImage
-
- pascal void TStdPrintHandler::SetPage(long aPageNumber)
- {
- VRect viewedRect;
- VPoint strip;
-
- fFocusedPage = aPageNumber;
- strip = this->PageToStrip(aPageNumber);
- for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
- {
- this->GetBreakCoord(gOrthogonal[vhs], strip[vhs], viewedRect[topLeft][vhs]);
- this->GetBreakCoord(gOrthogonal[vhs], strip[vhs] + 1, viewedRect[botRight][vhs]);
- }
-
- this->SetPageInterior(aPageNumber);
- fView->DoSetPageOffset(viewedRect[topLeft]);
- fViewedRect = viewedRect;
-
- #if qDebug
- if (gDebugPrinting)
- cout << form("pg #: %1d;", aPageNumber) << " coord == " << viewedRect[topLeft] << " Page Interior: " << fPageAreas.theInterior << "\n";
- #endif
-
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintNonRes
-
- pascal void TStdPrintHandler::SetPageInterior(long pageNumber)// override
- {
- VPoint pegPoint;
-
- for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
- {
- fPageAreas.theInterior[topLeft][vhs] = fPageAreas.thePaper[topLeft][vhs] + fPageAreas.theMargins[topLeft][vhs];
- fPageAreas.theInterior[botRight][vhs] = fPageAreas.theInterior[topLeft][vhs] + fViewPerPage[vhs];
- }
-
- this->LocatePageInterior(pageNumber, pegPoint);
- fPageAreas.theInterior[topLeft] = pegPoint;
- for (vhs = vSel; vhs <= hSel; ++vhs)
- fPageAreas.theInterior[botRight][vhs] = fPageAreas.theInterior[topLeft][vhs] + fViewPerPage[vhs];
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintImage
-
- pascal void TStdPrintHandler::SetPageOffset(const VPoint& coord)// override
- {
- for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
- gPageOffset[vhs] = coord[vhs] - fPageAreas.theInterior[topLeft][vhs];
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintFinder
-
- pascal Boolean TStdPrintHandler::SetupForFinder(void)// override
- {
- Boolean proceed;
- Boolean didChange;
-
- proceed = TRUE;
- this->CheckPrinter(); // Uncertain if necessary???
-
- if (fFinderSetup)
- this->PosePageSetupDialog(proceed, FALSE);
-
- if (proceed)
- {
- this->ShowDocBeingPrinted(TRUE);
- if (fFinderJobDialog ||!gFinderHPrint)
- {
- proceed = this->PoseJobDialog();
- // Merge into gPrintHandler, in case next document needs it
- if (!gFinderHPrint)
- gFinderHPrint = NewPermHandle(sizeof(TPrint));
-
- BlockMove((*fHPrint), (*gFinderHPrint), sizeof(TPrint));
- }
- else
- {
- PrJobMerge((THPrint)gFinderHPrint, (THPrint)fHPrint);
- this->ValidatePrintRecord(didChange);
- }
- this->ShowDocBeingPrinted(FALSE);
- }
- return proceed;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal Boolean TStdPrintHandler::SetupPrintOne(void)
- {
- Boolean didChange;
-
- // Call PrValidate to 1) make sure the record is OK, and
- // 2) Get the LaserWriter driver to get the name of the front window.
- this->ValidatePrintRecord(didChange);
-
- PrSetError(noErr);
- ((TPPrint) * fHPrint)->prJob.iFstPage = 0;
- ((TPPrint) * fHPrint)->prJob.iLstPage = 9999;// This is what the Print Mgr. uses
- return TRUE; // Should always be able to continue from here
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintFinder
-
- pascal void TStdPrintHandler::ShowDocBeingPrinted(Boolean entering)
- {
- Str255 aTitle;
-
- if (entering)
- {
- fPrintDialog = GetNewDialog(phWhichDoc, (Ptr)NULL, (WindowPtr) - 1);
- if (fPrintDialog)
- {
- this->GetDocName(aTitle);
- SetWTitle(fPrintDialog, aTitle);
- DrawDialog(fPrintDialog);
- }
- #if qDebug
- else
- ProgramBreak(ConcatNumber("Unable to load dialog ", phWhichDoc));
- #endif
-
- }
- else
- this->BanishPrintDialog();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal Boolean TStdPrintHandler::ShowsOnScreen(void)
- {
- if (fView)
- return fView->IsVisible();
- else
- return FALSE;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal long TStdPrintHandler::StripToPage(long hStrip,
- long vStrip)
- {
- Point strip((short)vStrip, (short)hStrip);
- VHSelect ortho;
-
- ortho = gOrthogonal[fPageDirection];
- return strip[fPageDirection] * fPageStrips[ortho] + strip[ortho] + fStartPage;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintRes
-
- pascal void TStdPrintHandler::ValidatePrintRecord(Boolean& didChange)
- {
- FailInfo fi;
- CPrintDialogs aPrValidateDialog(didChange, fHPrint);
-
- if (!fi.CatchFailure())
- {
- this->DoInMacPrint((WhatToDoType) & CPrintDialogs::CallPrValidate, &aPrValidateDialog);
- fi.Success();
- }
- else
- this->Reset();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintDoCommand
-
- pascal void TPrintStyleChangeCommand::Initialize(void)// override
- {
- inherited::Initialize();
- fNewHPrint = NULL;
- fOldHPrint = NULL;
- fStdPrintHandler = NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintDoCommand
-
- pascal void TPrintStyleChangeCommand::IPrintStyleChangeCommand(TStdPrintHandler* itsPrintHandler)
- {
- TDocument * changedDocument;
- FailInfo fi;
-
- changedDocument = itsPrintHandler->fDocument;
- this->ICommand(cChangePrinterStyle, changedDocument, itsPrintHandler->fView);
- fStdPrintHandler = itsPrintHandler;
- fCausesChange = (changedDocument && (changedDocument->fSavePrintInfo));
- if (!fi.CatchFailure())
- {
- fOldHPrint = NewPermHandle(sizeof(TPrint));
- // Make a copy of the old version of the PrintInfo record
- BlockMove(*(itsPrintHandler->fHPrint), *fOldHPrint, sizeof(TPrint));
- fNewHPrint = NewPermHandle(sizeof(TPrint));
- fi.Success();
- }
- else
- {
- this->Free();
- fi.ReSignal();
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintDoCommand
-
- pascal void TPrintStyleChangeCommand::Free(void)// override
- {
- fOldHPrint = DisposeIfHandle(fOldHPrint);
- fNewHPrint = DisposeIfHandle(fNewHPrint);
- inherited::Free();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintDoCommand
-
- pascal void TPrintStyleChangeCommand::DoIt(void)// override
- {
- fStdPrintHandler->CheckPrinter(); // Will find it changed, and hence dispatch
- // to view's DoPrinterChanged
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintFields
-
- pascal void TPrintStyleChangeCommand::Fields(TObject* obj)
- {
- obj->DoToField("TPrintStyleChangeCommand", NULL, bClass);
- obj->DoToField("fStdPrintHandler", &fStdPrintHandler, bObject);
- obj->DoToField("fOldHPrint", &fOldHPrint, bHandle);
- obj->DoToField("fNewHPrint", &fNewHPrint, bHandle);
-
- inherited::Fields(obj);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintDoCommand
-
- pascal void TPrintStyleChangeCommand::UndoIt(void)// override
-
- {
- BlockMove(*fOldHPrint, *(fStdPrintHandler->fHPrint), sizeof(TPrint));
- fStdPrintHandler->CheckPrinter(); // Will find it changed, and hence dispatch
- // to view's DoPrinterChanged
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment PrintDoCommand
-
- pascal void TPrintStyleChangeCommand::RedoIt(void)// override
- {
- BlockMove(*fNewHPrint, *(fStdPrintHandler->fHPrint), sizeof(TPrint));
- fStdPrintHandler->CheckPrinter(); // Will find it changed, and hence dispatch
- // to view's DoPrinterChanged
- }
-
-
-