DocumentViewerImpl::PrintDocContent()
DocumentViewerImpl::PrintDocContent(PrintObject* aPO, nsresult& aStatus)
DocumentViewerImpl::PrintDocContent(){  NS_ASSERTION(mPrintDocList != nsnull, "mPrintDocList to print!");  nsCOMPtr<nsIDOMWindowInternal> domWinIntl(do_QueryInterface(mPrintDocDW));  // get the main parent WebShell  nsCOMPtr<nsIWebShell> webContainer(do_QueryInterface(mContainer));  //-----------------------------------------------------  // Now check to see if we can print the WebShells  //-----------------------------------------------------  PRInt16 printFrameType = nsIPrintOptions::kSelectedFrame; // XXX later this default to kFramesAsIs  PRInt16 printHowEnable = nsIPrintOptions::kFrameEnableNone;   PRInt16 printRangeType = nsIPrintOptions::kRangeAllPages;  nsresult rv;  NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv);  if (NS_SUCCEEDED(rv) && printService) {    printService->GetPrintFrameType(&printFrameType);    printService->GetHowToEnableFrameUI(&printHowEnable);    printService->GetPrintRange(&printRangeType);  }  nsCOMPtr<nsIDocument>  document;  nsCOMPtr<nsIPresShell> wsPresShell;  PRBool isSubDoc            = PR_FALSE;  PRBool canPrintFrame       = PR_FALSE;  PRBool printSelectedFrame  = PR_FALSE;  PRBool printSelectedIFrame = PR_FALSE;  // Walk the list of webshells to be printed and   // find the first one that "can" be printed.  //  // For example, if you have a frameset document with three frames and  // you are printing a selection in the second frame. This will skip  // the first frame, print the second and then laster clear the list   // of webshells to be printed.  nsIWebShell* webShell = nsnull;  while (!canPrintFrame && mPrintDocList->Count() > 0) {    webShell = (nsIWebShell*)mPrintDocList->ElementAt(0);    NS_ASSERTION(webShell, "The WebShell can't be NULL!");    // Now locate the nsIDocument for the WebShell    nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webShell));    NS_ASSERTION(docShell, "The DocShell can't be NULL!");    docShell->GetPresShell(getter_AddRefs(wsPresShell));    NS_ASSERTION(wsPresShell, "The PresShell can't be NULL!");    wsPresShell->GetDocument(getter_AddRefs(document));    NS_ASSERTION(document, "The Document can't be NULL!");    // Now see if we are printing a sub document    isSubDoc = webShell != webContainer.get();    // Remove the WebShell we are going to print    mPrintDocList->RemoveElementAt(0);    // Check to see if printing frames is not on     // and that we are printing a range or all pages    PRBool printAllPages  = (printRangeType == nsIPrintOptions::kRangeAllPages ||                             printRangeType == nsIPrintOptions::kRangeSpecifiedPageRange) &&                              printHowEnable == nsIPrintOptions::kFrameEnableNone;    // See if we are printing the selected frame    PRBool printEachFrame = printFrameType == nsIPrintOptions::kEachFrameSep;    // This is for when the current root WebShell is a Frameset    // and we need to see if the webshell being passed in     // is the currently selected frame of the frameset    //    // The aDOMWin is the currently selected DOM window,     // which could be a frameset frame or a IFrame    PRBool thisWebShellIsSelected = PR_FALSE;    nsCOMPtr<nsIScriptGlobalObject> scriptObj(do_QueryInterface(mPrintDocDW));    if (scriptObj) {      nsCOMPtr<nsIDocShell> docShell;      scriptObj->GetDocShell(getter_AddRefs(docShell));      if (docShell) {        nsCOMPtr<nsIWebShell> webShellForParent(do_QueryInterface(docShell));        if (webShellForParent.get() == webShell) {          thisWebShellIsSelected = PR_TRUE;        }      }    }    // Check to make we can print the currently selected frame of a frameset    printSelectedFrame = thisWebShellIsSelected &&                          printFrameType == nsIPrintOptions::kSelectedFrame;    // Now see if we can print the selected IFrame    // When IFrames are selected all the frame UI is turned off    // and theuser prints it by selected the "Selection" radiobutton    // which turns on kRangeSelection    printSelectedIFrame  = PR_FALSE;    if (printHowEnable == nsIPrintOptions::kFrameEnableNone &&         printRangeType == nsIPrintOptions::kRangeSelection &&        thisWebShellIsSelected) {      printSelectedIFrame = PR_TRUE;      // check to see if we have a range selection,       // as oppose to a insert selection      // this means if the user just clicked on the IFrame then       // there will not be a selection so we want the entire page to print      //      // XXX this is sort of a hack right here to make the page       // not try to reposition itself when printing selection      if (!IsThereASelection(domWinIntl)) {        printRangeType = nsIPrintOptions::kRangeAllPages;        printService->SetPrintRange(printRangeType);      }    }    canPrintFrame = printAllPages || printEachFrame || printSelectedFrame || printSelectedIFrame;                                                            }  if (webShell != nsnull && (!isSubDoc || (isSubDoc && canPrintFrame))) {    // If we printing the selected frame and     // there are other WebShells in the list then clear the list     if (printSelectedFrame) {      mPrintDocList->Clear();    }    PRInt32 width, height;    mPrintDocDC->GetDeviceSurfaceDimensions(width, height);    // XXX - Hack Alert    // OK,  so ther eis a selection, we will print the entire selection     // on one page and then crop the page.    // This means you can never print any selection that is longer than one page    // put it keeps it from page breaking in the middle of your print of the selection    // (see also nsSimplePageSequence.cpp)    if (IsThereASelection(domWinIntl)) {      height = 0x0FFFFFFF;    }    nsCOMPtr<nsIPrintContext> printcon(do_CreateInstance(kPrintContextCID,&rv));    if (NS_FAILED(rv)) {      return rv;    } else {      rv = printcon->QueryInterface(NS_GET_IID(nsIPresContext), (void**)&mPrintPresContext);      if (NS_FAILED(rv)) {        return rv;      }    }    mPrintPresContext->Init(mPrintDocDC);    CreateStyleSet(document, &mPrintStyleSet);    rv = nsComponentManager::CreateInstance(kPresShellCID,                                            nsnull,                                            NS_GET_IID(nsIPresShell),                                            (void **)&mPrintPresShell);    if (NS_FAILED(rv)) {      return rv;    }    rv = nsComponentManager::CreateInstance(kViewManagerCID,                                            nsnull,                                            NS_GET_IID(nsIViewManager),                                            (void **)&mPrintViewManager);    if (NS_FAILED(rv)) {      return rv;    }    rv = mPrintViewManager->Init(mPrintDocDC);    if (NS_FAILED(rv)) {      return rv;    }    nsRect tbounds = nsRect(0, 0, width, height);    // Create a child window of the parent that is our "root view/window"    nsIView* rootView;    rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&rootView);    if (NS_FAILED(rv)) {      return rv;    }    rv = rootView->Init(mPrintViewManager, tbounds, nsnull);    if (NS_FAILED(rv)) {      return rv;    }    // Setup hierarchical relationship in view manager    mPrintViewManager->SetRootView(rootView);    mPrintPresShell->Init(document, mPrintPresContext, mPrintViewManager, mPrintStyleSet);    nsCompatibility mode;    mPresContext->GetCompatibilityMode(&mode);    mPrintPresContext->SetCompatibilityMode(mode);    mPrintPresContext->SetContainer(webShell);    // get the old history    nsCOMPtr<nsIPresShell> presShell;    nsCOMPtr<nsILayoutHistoryState>  layoutState;    NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE);    presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE);    mPrintPresShell->BeginObservingDocument();    //lay it out...    mPrintPresShell->InitialReflow(width, height);    // Transfer Selection Ranges to the new Print PresShell    nsCOMPtr<nsISelection> selection;    nsCOMPtr<nsISelection> selectionPS;    nsresult rvv = GetDocumentSelection(getter_AddRefs(selection), wsPresShell);    if (NS_SUCCEEDED(rvv) && selection) {      rvv = GetDocumentSelection(getter_AddRefs(selectionPS), mPrintPresShell);      if (NS_SUCCEEDED(rvv) && selectionPS) {        PRInt32 cnt;        selection->GetRangeCount(&cnt);        PRInt32 inx;        for (inx=0;inx<cnt;inx++) {          nsCOMPtr<nsIDOMRange> range;          if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range)))) {            selectionPS->AddRange(range);          }        }      }    }              // update the history from the old presentation shell    nsCOMPtr<nsIFrameManager> fm;    rv = mPrintPresShell->GetFrameManager(getter_AddRefs(fm));    if(NS_SUCCEEDED(rv) && fm) {      nsIFrame* root;      mPrintPresShell->GetRootFrame(&root);      fm->RestoreFrameState(mPrintPresContext, root, layoutState);    }    mPrintPresShell->EndObservingDocument();    // Ask the page sequence frame to print all the pages    nsIPageSequenceFrame* pageSequence;    //     mPrintPresShell->GetPageSequenceFrame(&pageSequence);    NS_ASSERTION(nsnull != pageSequence, "no page sequence frame");         if (nsnull != mFilePointer) {      // output the regression test      nsIFrameDebug* fdbg;      nsIFrame* root;      mPrintPresShell->GetRootFrame(&root);      if (NS_SUCCEEDED(root->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**) &fdbg))) {        fdbg->DumpRegressionData(mPrintPresContext, mFilePointer, 0, PR_TRUE);      }      fclose(mFilePointer);          } else {      nsIFrame* rootFrame;      mPrintPresShell->GetRootFrame(&rootFrame);#if defined(DEBUG_rods) || defined(DEBUG_dcone)      DumpLayoutData(mPrintPresContext, mPrintDocDC, rootFrame, webShell);#endif      if (printService) {        // get the document title        const nsString* docTitle = document->GetDocumentTitle();        if( docTitle != nsnull) {          PRUnichar * docStr = docTitle->ToNewUnicode();          printService->SetTitle(docStr);          nsMemory::Free(docStr);        }        // Get Document URL String        nsCOMPtr<nsIURI> url(getter_AddRefs(document->GetDocumentURL()));        char * urlCStr;        url->GetSpec(&urlCStr);        nsAutoString urlStr;        urlStr.AssignWithConversion(urlCStr);        PRUnichar * urlUStr = urlStr.ToNewUnicode();        printService->SetDocURL(urlUStr);        nsMemory::Free(urlUStr);        nsMemory::Free(urlCStr);        if (nsIPrintOptions::kRangeSelection == printRangeType) {          mPrintPresContext->SetIsRenderingOnlySelection(PR_TRUE);          // temporarily creating rendering context          // which is needed to dinf the selection frames          nsCOMPtr<nsIRenderingContext> rc;          mPrintDocDC->CreateRenderingContext(*getter_AddRefs(rc));          // find the starting and ending page numbers          // via the selection          nsIFrame* startFrame;          nsIFrame* endFrame;          PRInt32   startPageNum;          PRInt32   endPageNum;          nsRect    startRect;          nsRect    endRect;          rv = GetPageRangeForSelection(mPrintPresShell, mPrintPresContext, *rc, selectionPS, pageSequence,                                         &startFrame, startPageNum, startRect,                                         &endFrame, endPageNum, endRect);          if (NS_SUCCEEDED(rv)) {            printService->SetStartPageRange(startPageNum);            printService->SetEndPageRange(endPageNum);            if (startPageNum == endPageNum) {              nsIFrame * seqFrame;              if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {                return NS_ERROR_FAILURE;              }              nsRect rect(0,0,0,0);              nsRect areaRect;              nsIFrame * areaFrame = FindFrameByType(mPrintPresContext, startFrame, nsHTMLAtoms::body, rect, areaRect);              if (areaFrame) {                areaRect.y = areaRect.y - startRect.y;                areaFrame->SetRect(mPrintPresContext, areaRect);              }            }          }        }        nsIFrame * seqFrame;        if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) {          return NS_ERROR_FAILURE;        }        nsRect srect;        seqFrame->GetRect(srect);        nsRect r;        rootView->GetBounds(r);        r.height = srect.height;        rootView->SetBounds(r);        rootFrame->GetRect(r);        r.height = srect.height;        rootFrame->SetRect(mPrintPresContext, r);        mPageSeqFrame = pageSequence;        mPageSeqFrame->StartPrint(mPrintPresContext, printService);        // Get the delay time in between the printing of each page        // this gives the user more time to press cancel        PRInt32 printPageDelay = 500;        printService->GetPrintPageDelay(&printPageDelay);        // SetupToPrintContent sets mTimerAlreadyStarted to PR_FALSE in        // preparation for printing. Start only happens the first time        // Then we must re-init it with the new mPrintPresContext         if (!mTimerAlreadyStarted) {          mTimerAlreadyStarted = PR_TRUE;          StartPagePrintTimer(mPrintPresContext, printService, printPageDelay);        } else {           mPagePrintTimer->Init(this, mPrintPresContext, printService, printPageDelay);        }      } else {        // not sure what to do here!        return NS_ERROR_FAILURE;      }    }  }  if (printSelectedIFrame) {    printService->SetPrintRange(nsIPrintOptions::kRangeSelection);  }  return NS_OK;}