ShowPrintErrorDialog(rv);
nsPrintEngine::ShowPrintErrorDialog(rv);
DocumentViewerImpl::Print(nsIPrintSettings*       aPrintSettings,                          nsIWebProgressListener* aWebProgressListener){#ifdef EXTENDED_DEBUG_PRINTING  // need for capturing result on each doc and sub-doc that is printed  gDumpFileNameCnt   = 0;  gDumpLOFileNameCnt = 0;#if defined(XP_PC)  if (kPrintingLogMod && kPrintingLogMod->level == DUMP_LAYOUT_LEVEL) {    RemoveFilesInDir(".\\");  }#endif // XP_PC#endif // EXTENDED_DEBUG_PRINTING  // Temporary code for Bug 136185  nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));  if (xulDoc) {    ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_NO_XUL);    return NS_ERROR_FAILURE;  }  nsresult rv = NS_ERROR_FAILURE;  nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(mContainer));  NS_ASSERTION(docShell, "This has to be a docshell");  // Check to see if this document is still busy  // If it is busy and we aren't already "queued" up to print then  // Indicate there is a print pending and cache the args for later  PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE;  if ((NS_FAILED(docShell->GetBusyFlags(&busyFlags)) ||       (busyFlags != nsIDocShell::BUSY_FLAGS_NONE && busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)) &&       !mPrintDocIsFullyLoaded) {    if (!mPrintIsPending) {      mCachedPrintSettings           = aPrintSettings;      mCachedPrintWebProgressListner = aWebProgressListener;      mPrintIsPending                = PR_TRUE;    }    return NS_OK;  }  nsCOMPtr<nsIPresShell> presShell;  docShell->GetPresShell(getter_AddRefs(presShell));  if (!presShell) {    // A frame that's not displayed can't be printed!    PR_PL(("Printing Stopped - PreShell was NULL!"));    return NS_OK;  }  if (mIsDoingPrintPreview) {    PRBool okToPrint = PR_FALSE;    nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));    if (prefs) {      prefs->GetBoolPref("print.whileInPrintPreview", &okToPrint);    }    if (!okToPrint) {      ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_PRINT_WHILE_PREVIEW, PR_FALSE);      return NS_OK;    }  }  // if we are printing another URL, then exit  // the reason we check here is because this method can be called while  // another is still in here (the printing dialog is a good example).  // the only time we can print more than one job at a time is the regression tests  if (mIsDoingPrinting) {    // Let the user know we are not ready to print.    rv = NS_ERROR_NOT_AVAILABLE;    ShowPrintErrorDialog(rv);    return rv;  }    mPrt = new PrintData(PrintData::eIsPrinting);  if (!mPrt) {    PR_PL(("NS_ERROR_OUT_OF_MEMORY - Creating PrintData"));    return NS_ERROR_OUT_OF_MEMORY;  }  // if they don't pass in a PrintSettings, then get the Global PS  mPrt->mPrintSettings = aPrintSettings;  if (!mPrt->mPrintSettings) {    GetGlobalPrintSettings(getter_AddRefs(mPrt->mPrintSettings));  }  mPrt->mPrintOptions = do_GetService(sPrintOptionsContractID, &rv);  if (NS_SUCCEEDED(rv) && mPrt->mPrintOptions && mPrt->mPrintSettings) {    // Get the default printer name and set it into the PrintSettings    rv = CheckForPrinters(mPrt->mPrintOptions, mPrt->mPrintSettings, NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE, PR_TRUE);  } else {    NS_ASSERTION(mPrt->mPrintSettings, "You can't Print without a PrintSettings!");    rv = NS_ERROR_FAILURE;  }  // Create a print session and let the print settings know about it.  // The print settings hold an nsWeakPtr to the session so it does not  // need to be cleared from the settings at the end of the job.  mPrt->mPrintSession = do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);  mPrt->mPrintSettings->SetPrintSession(mPrt->mPrintSession);  if (NS_FAILED(rv)) {    delete mPrt;    PR_PL(("NS_ERROR_FAILURE - CheckForPrinters for Printers failed"));    mPrt = nsnull;    return NS_ERROR_FAILURE;  }    mPrt->mPrintSettings->SetIsCancelled(PR_FALSE);  mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);  // Let's print ...  mIsDoingPrinting = PR_TRUE;  // We need to  make sure this document doesn't get unloaded  // before we have a chance to print, so this stops the Destroy from  // being called  mPrt->mPreparingForPrint = PR_TRUE;  if (aWebProgressListener != nsnull) {    mPrt->mPrintProgressListeners.AppendElement((void*)aWebProgressListener);    NS_ADDREF(aWebProgressListener);  }  // Get the currently focused window and cache it  // because the Print Dialog will "steal" focus and later when you try  // to get the currently focused windows it will be NULL  mPrt->mCurrentFocusWin = getter_AddRefs(FindFocusedDOMWindowInternal());  // Check to see if there is a "regular" selection  PRBool isSelection = IsThereARangeSelection(mPrt->mCurrentFocusWin);  // Create a list for storing the WebShells that need to be printed  if (mPrt->mPrintDocList == nsnull) {    mPrt->mPrintDocList = new nsVoidArray();    if (mPrt->mPrintDocList == nsnull) {      mIsDoingPrinting = PR_FALSE;      delete mPrt;      mPrt = nsnull;      PR_PL(("NS_ERROR_FAILURE - Couldn't create mPrintDocList"));      return NS_ERROR_FAILURE;    }  } else {    mPrt->mPrintDocList->Clear();  }  // Get the webshell for this documentviewer  nsCOMPtr<nsIWebShell> webContainer(do_QueryInterface(mContainer));  // Add Root Doc to Tree and List  mPrt->mPrintObject             = new PrintObject;  mPrt->mPrintObject->mWebShell  = webContainer;  mPrt->mPrintDocList->AppendElement(mPrt->mPrintObject);  mPrt->mIsParentAFrameSet = IsParentAFrameSet(webContainer);  mPrt->mPrintObject->mFrameType = mPrt->mIsParentAFrameSet?eFrameSet:eDoc;  // Build the "tree" of PrintObjects  nsCOMPtr<nsIDocShellTreeNode>  parentAsNode(do_QueryInterface(webContainer));  BuildDocTree(parentAsNode, mPrt->mPrintDocList, mPrt->mPrintObject);  // Create the linkage from the suv-docs back to the content element  // in the parent document  MapContentToWebShells(mPrt->mPrintObject, mPrt->mPrintObject);  // Get whether the doc contains a frameset  // Also, check to see if the currently focus webshell  // is a child of this webshell  mPrt->mIsIFrameSelected = IsThereAnIFrameSelected(webContainer, mPrt->mCurrentFocusWin, mPrt->mIsParentAFrameSet);  CheckForHiddenFrameSetFrames();  DUMP_DOC_LIST("\nAfter Mapping------------------------------------------");  rv = NS_ERROR_FAILURE;  // Setup print options for UI  if (mPrt->mIsParentAFrameSet) {    if (mPrt->mCurrentFocusWin) {      mPrt->mPrintSettings->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll);    } else {      mPrt->mPrintSettings->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAsIsAndEach);    }  } else {    mPrt->mPrintSettings->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableNone);  }  // Now determine how to set up the Frame print UI  mPrt->mPrintSettings->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, isSelection || mPrt->mIsIFrameSelected);#ifdef PR_LOGGING  if (mPrt->mPrintSettings) {    PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone;    mPrt->mPrintSettings->GetHowToEnableFrameUI(&printHowEnable);    PRBool val;    mPrt->mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &val);    PR_PL(("********* DocumentViewerImpl::Print *********\n"));    PR_PL(("IsParentAFrameSet:   %s \n", PRT_YESNO(mPrt->mIsParentAFrameSet)));    PR_PL(("IsIFrameSelected:    %s \n", PRT_YESNO(mPrt->mIsIFrameSelected)));    PR_PL(("Main Doc Frame Type: %s \n", gFrameTypesStr[mPrt->mPrintObject->mFrameType]));    PR_PL(("HowToEnableFrameUI:  %s \n", gFrameHowToEnableStr[printHowEnable]));    PR_PL(("EnableSelectionRB:   %s \n", PRT_YESNO(val)));    PR_PL(("*********************************************\n"));  }#endif  /* create factory (incl. create print dialog) */  nsCOMPtr<nsIDeviceContextSpecFactory> factory =          do_CreateInstance(kDeviceContextSpecFactoryCID, &rv);  if (NS_SUCCEEDED(rv)) {#ifdef DEBUG_dcone    printf("PRINT JOB STARTING\n");#endif    nsCOMPtr<nsIDeviceContextSpec> devspec;    nsCOMPtr<nsIDeviceContext> dx;    mPrt->mPrintDC = nsnull; // XXX why?#ifdef NS_DEBUG    mPrt->mDebugFilePtr = mDebugFile;#endif    PRBool printSilently;    mPrt->mPrintSettings->GetPrintSilent(&printSilently);    // Ask dialog to be Print Shown via the Plugable Printing Dialog Service    // This service is for the Print Dialog and the Print Progress Dialog    // If printing silently or you can't get the service continue on    if (!printSilently) {      nsCOMPtr<nsIPrintingPromptService> printPromptService(do_GetService(kPrintingPromptService));      if (printPromptService) {        nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject;        mDocument->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject));        if (!scriptGlobalObject) return nsnull;        nsCOMPtr<nsIDOMWindow> domWin = do_QueryInterface(scriptGlobalObject);         if (!domWin) return nsnull;        // Platforms not implementing a given dialog for the service may        // return NS_ERROR_NOT_IMPLEMENTED or an error code.        //        // NS_ERROR_NOT_IMPLEMENTED indicates they want default behavior        // Any other error code means we must bail out        //        rv = printPromptService->ShowPrintDialog(domWin, this, mPrt->mPrintSettings);        if (rv == NS_ERROR_NOT_IMPLEMENTED) {          // This means the Dialog service was there,           // but they choose not to implement this dialog and           // are looking for default behavior from the toolkit          rv = NS_OK;        } else if (NS_SUCCEEDED(rv)) {          // since we got the dialog and it worked then make sure we           // are telling GFX we want to print silent          printSilently = PR_TRUE;        }      } else {        rv = NS_ERROR_GFX_NO_PRINTROMPTSERVICE;      }    }    if (NS_FAILED(rv)) {      if (rv != NS_ERROR_ABORT) {        ShowPrintErrorDialog(rv);      }      delete mPrt;      mPrt = nsnull;      PR_PL(("**** Printing Stopped before CreateDeviceContextSpec"));      return rv;    }    // Create DeviceSpec for Printing    rv = factory->CreateDeviceContextSpec(mWindow, mPrt->mPrintSettings, *getter_AddRefs(devspec), PR_FALSE);    // If the page was intended to be destroyed while we were in the print dialog     // then we need to clean up and abort the printing.    if (mPrt->mDocWasToBeDestroyed) {      mPrt->mPreparingForPrint = PR_FALSE;      Destroy();      mIsDoingPrinting = PR_FALSE;      // If they hit cancel then rv will equal NS_ERROR_ABORT and       // then we don't want to display the message      if (rv != NS_ERROR_ABORT) {        ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_DOC_WAS_DESTORYED);      }      PR_PL(("**** mDocWasToBeDestroyed - %s", rv != NS_ERROR_ABORT?"NS_ERROR_GFX_PRINTER_DOC_WAS_DESTORYED":"NS_ERROR_ABORT"));      return NS_ERROR_ABORT;    }    if (NS_SUCCEEDED(rv)) {      rv = mPresContext->GetDeviceContext(getter_AddRefs(dx));      if (NS_SUCCEEDED(rv)) {        rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC));        if (NS_SUCCEEDED(rv)) {          // Get the Original PixelScale incase we need to start changing it          mPrt->mPrintDC->GetCanonicalPixelScale(mPrt->mOrigDCScale);          // Shrink to Fit over rides and scaling values          if (!mPrt->mShrinkToFit) {            double scaling;            mPrt->mPrintSettings->GetScaling(&scaling);            mPrt->mPrintDC->SetCanonicalPixelScale(float(scaling)*mPrt->mOrigDCScale);          }          if(webContainer) {#ifdef DEBUG_dcone            float   a1,a2;            PRInt32 i1,i2;            printf("CRITICAL PRINTING INFORMATION\n");            // DEVICE CONTEXT INFORMATION from PresContext            printf("DeviceContext of Presentation Context(%x)\n",dx);            dx->GetDevUnitsToTwips(a1);            dx->GetTwipsToDevUnits(a2);            printf("    DevToTwips = %f TwipToDev = %f\n",a1,a2);            dx->GetAppUnitsToDevUnits(a1);            dx->GetDevUnitsToAppUnits(a2);            printf("    AppUnitsToDev = %f DevUnitsToApp = %f\n",a1,a2);            dx->GetCanonicalPixelScale(a1);            printf("    GetCanonicalPixelScale = %f\n",a1);            dx->GetScrollBarDimensions(a1, a2);            printf("    ScrollBar x = %f y = %f\n",a1,a2);            dx->GetZoom(a1);            printf("    Zoom = %f\n",a1);            dx->GetDepth((PRUint32&)i1);            printf("    Depth = %d\n",i1);            dx->GetDeviceSurfaceDimensions(i1,i2);            printf("    DeviceDimension w = %d h = %d\n",i1,i2);            // DEVICE CONTEXT INFORMATION            printf("DeviceContext created for print(%x)\n",mPrt->mPrintDC);            mPrt->mPrintDC->GetDevUnitsToTwips(a1);            mPrt->mPrintDC->GetTwipsToDevUnits(a2);            printf("    DevToTwips = %f TwipToDev = %f\n",a1,a2);            mPrt->mPrintDC->GetAppUnitsToDevUnits(a1);            mPrt->mPrintDC->GetDevUnitsToAppUnits(a2);            printf("    AppUnitsToDev = %f DevUnitsToApp = %f\n",a1,a2);            mPrt->mPrintDC->GetCanonicalPixelScale(a1);            printf("    GetCanonicalPixelScale = %f\n",a1);            mPrt->mPrintDC->GetScrollBarDimensions(a1, a2);            printf("    ScrollBar x = %f y = %f\n",a1,a2);            mPrt->mPrintDC->GetZoom(a1);            printf("    Zoom = %f\n",a1);            mPrt->mPrintDC->GetDepth((PRUint32&)i1);            printf("    Depth = %d\n",i1);            mPrt->mPrintDC->GetDeviceSurfaceDimensions(i1,i2);            printf("    DeviceDimension w = %d h = %d\n",i1,i2);#endif /* DEBUG_dcone */            // Always check and set the print settings first and then fall back            // onto the PrintService if there isn't a PrintSettings            //            // Posiible Usage values:            //   nsIPrintSettings::kUseInternalDefault            //   nsIPrintSettings::kUseSettingWhenPossible            //            // NOTE: The consts are the same for PrintSettings and PrintSettings            PRInt16 printFrameTypeUsage = nsIPrintSettings::kUseSettingWhenPossible;            mPrt->mPrintSettings->GetPrintFrameTypeUsage(&printFrameTypeUsage);            // Ok, see if we are going to use our value and override the default            if (printFrameTypeUsage == nsIPrintSettings::kUseSettingWhenPossible) {              // Get the Print Options/Settings PrintFrameType to see what is preferred              PRInt16 printFrameType = nsIPrintSettings::kEachFrameSep;              mPrt->mPrintSettings->GetPrintFrameType(&printFrameType);              // Don't let anybody do something stupid like try to set it to              // kNoFrames when we are printing a FrameSet              if (printFrameType == nsIPrintSettings::kNoFrames) {                mPrt->mPrintFrameType = nsIPrintSettings::kEachFrameSep;                mPrt->mPrintSettings->SetPrintFrameType(mPrt->mPrintFrameType);              } else {                // First find out from the PrinService what options are available                // to us for Printing FrameSets                PRInt16 howToEnableFrameUI;                mPrt->mPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI);                if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) {                  switch (howToEnableFrameUI) {                    case nsIPrintSettings::kFrameEnableAll:                      mPrt->mPrintFrameType = printFrameType;                      break;                    case nsIPrintSettings::kFrameEnableAsIsAndEach:                      if (printFrameType != nsIPrintSettings::kSelectedFrame) {                        mPrt->mPrintFrameType = printFrameType;                      } else { // revert back to a good value                        mPrt->mPrintFrameType = nsIPrintSettings::kEachFrameSep;                      }                      break;                  } // switch                  mPrt->mPrintSettings->SetPrintFrameType(mPrt->mPrintFrameType);                }              }            } else {              mPrt->mPrintSettings->GetPrintFrameType(&mPrt->mPrintFrameType);            }            // Get the Needed info for Calling PrepareDocument            PRUnichar* fileName = nsnull;            // check to see if we are printing to a file            PRBool isPrintToFile = PR_FALSE;            mPrt->mPrintSettings->GetPrintToFile(&isPrintToFile);            if (isPrintToFile) {              // On some platforms The PrepareDocument needs to know the name of the file              // and it uses the PrintService to get it, so we need to set it into the PrintService here              mPrt->mPrintSettings->GetToFileName(&fileName);            }            PRUnichar * docTitleStr;            PRUnichar * docURLStr;            GetDisplayTitleAndURL(mPrt->mPrintObject, mPrt->mPrintSettings, mPrt->mBrandName, &docTitleStr, &docURLStr, eDocTitleDefURLDoc);             PR_PL(("Title: %s\n", docTitleStr?NS_LossyConvertUCS2toASCII(docTitleStr).get():""));            PR_PL(("URL:   %s\n", docURLStr?NS_LossyConvertUCS2toASCII(docURLStr).get():""));            rv = mPrt->mPrintDC->PrepareDocument(docTitleStr, fileName);            if (docTitleStr) nsMemory::Free(docTitleStr);            if (docURLStr) nsMemory::Free(docURLStr);            NS_ENSURE_SUCCESS(rv, rv);            PRBool doNotify;            ShowPrintProgress(PR_TRUE, doNotify);            if (!doNotify) {              // Print listener setup...              if (mPrt != nsnull) {                mPrt->OnStartPrinting();                  }              rv = DocumentReadyForPrinting();            }          }        }      }    } else {      mPrt->mPrintSettings->SetIsCancelled(PR_TRUE);    }  }  /* cleaup on failure + notify user */  if (NS_FAILED(rv)) {    CleanUpBeforeReflow(rv);  }  return rv;}