void nsTopProgressManager::UpdateProgressBar(AggregateTransferInfo& info) { if (info.MSecRemaining == 0) return; if (info.SuspendedCount > 0) { // turn on the strobe... FE_SetProgressBarPercent(fContext, 0); return; } nsInt64 dt = nsTime(PR_Now()) - fProgressBarStart; PRUint32 elapsed = dt / nsInt64((PRUint32) PR_USEC_PER_MSEC); // Compute the percent complete, that is, elapsed / (elapsed + remaining) double p = ((double) elapsed) / ((double) (elapsed + info.MSecRemaining)); PRUint32 pctComplete = (PRUint32) (100.0 * p); #define MONOTONIC_PROGRESS_BAR #if defined(MONOTONIC_PROGRESS_BAR) // This hackery is a kludge to make the progress bar // monotonically increase rather than slipping backwards as we // discover that there's more content to download. It works by // adjusting the progress manager's start time backwards to // make the elapsed time (time we've waited so far) seem // larger in proportion to the amount of time that appears to // be left. if (pctComplete < fProgress) { PRUint32 newElapsed = (PRUint32) ((p * ((double) info.MSecRemaining)) / (1.0 - p)); PRInt32 dMSec = newElapsed - elapsed; if (dMSec > 0) fProgressBarStart -= nsInt64(dMSec * ((PRUint32) PR_USEC_PER_MSEC)); // Progress bar hasn't changed -- don't bother updating it. return; } #endif fProgress = pctComplete; FE_SetProgressBarPercent(fContext, fProgress); }
void nsTopProgressManager::UpdateStatusMessage(AggregateTransferInfo& info) { // Compute how much time has elapsed nsInt64 dt = nsTime(PR_Now()) - fActualStart; PRUint32 elapsed = dt / nsInt64((PRUint32) PR_USEC_PER_SEC); char buf[256]; *buf = 0; if (info.ObjectCount == 1 || info.CompleteCount == 0) { // If we only have one object that we're transferring, or if // nothing has completed yet, show the default status message PL_strncpy(buf, fDefaultStatus, sizeof(buf)); } if (elapsed > TIME_UNTIL_DETAILS) { char details[256]; *details = 0; if (!info.UnknownLengthCount && info.ContentLength > 0) { formatKnownContentLength(details, sizeof(details), info.BytesReceived, info.ContentLength, elapsed); } else if (info.BytesReceived > 0) { formatUnknownContentLength(details, sizeof(details), info.BytesReceived, elapsed); } if (*details) { // XXX needs to go to allxpstr.h if (*buf) PL_strcatn(buf, sizeof(buf), ", "); PL_strcatn(buf, sizeof(buf), details); } } FE_Progress(fContext, buf); }
NS_IMETHODIMP nsScriptPaginator::AdjustSynchronously () { nsCOMPtr<nsIDOMXPathEvaluator> xpe = do_CreateInstance( "@mozilla.org/dom/xpath-evaluator;1"); nsCOMPtr<nsIDOMXPathResult> result; nsresult rv = xpe->Evaluate( NS_LITERAL_STRING("//div[@class='softbreak' or @class='hardbreak']"), mScript, nsnull, nsIDOMXPathResult::ORDERED_NODE_ITERATOR_TYPE, nsnull, getter_AddRefs(result)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIDOMNSHTMLElement> lastbreak; nsCOMPtr<nsIDOMNSHTMLElement> pagebreak; nsCOMPtr<nsIDOMNode> cursor; PRUint32 breaknum = 0; rv = result->IterateNext(getter_AddRefs(cursor)); while (NS_SUCCEEDED(rv) && cursor) { pagebreak = do_QueryInterface(cursor); if (pagebreak) { PRInt32 offset = 0; pagebreak->GetOffsetTop(&offset); if (breaknum >= mPageBreakOffsets.Length() || PRUint32(offset) != mPageBreakOffsets[breaknum]) break; lastbreak = pagebreak; ++breaknum; } rv = result->IterateNext(getter_AddRefs(cursor)); } if (NS_FAILED(rv)) return rv; CalculateFontMetrics(); // Adjust from the last valid page break (or the start) onwards if (lastbreak) { nsCOMPtr<nsIDOMNode> lastbreaknode(do_QueryInterface(lastbreak)); lastbreaknode->GetNextSibling(getter_AddRefs(cursor)); } else { nsCOMPtr<nsIDOMHTMLDocument> hdoc(do_QueryInterface(mScript)); hdoc->GetFirstChild(getter_AddRefs(cursor)); } PRUint16 nodeType = 0; while (cursor) { cursor->GetNodeType(&nodeType); if (nodeType == nsIDOMNode::ELEMENT_NODE) break; nsCOMPtr<nsIDOMNode> tmp; cursor->GetNextSibling(getter_AddRefs(tmp)); cursor = tmp; } mNextPageStartsAt = cursor; mCurPageBreakNum = breaknum; mEditor->BeginTransaction(); while (mNextPageStartsAt) AdjustNextPageBreak(); mEditor->EndTransaction(); mPageCount = mPageBreakOffsets.Length() + 1; mLastPaginationEnded = nsTime(); return NS_OK; }
NS_IMETHODIMP nsScriptPaginator::AdjustPageBreaks () { // Update less frequently if we're not in the middle of pagination if ((mUpdateCount++ % 5) != 0 && ! mNextPageStartsAt) return NS_OK; PRInt32 modificationCount; mEditor->GetModificationCount(&modificationCount); if (modificationCount == mModificationCount) return NS_OK; mModificationCount = modificationCount; nsCOMPtr<nsIDOMXPathEvaluator> xpe = do_CreateInstance( "@mozilla.org/dom/xpath-evaluator;1"); nsCOMPtr<nsIDOMXPathResult> result; nsresult rv = xpe->Evaluate( NS_LITERAL_STRING("//div[@class='softbreak' or @class='hardbreak']"), mScript, nsnull, nsIDOMXPathResult::ORDERED_NODE_ITERATOR_TYPE, nsnull, getter_AddRefs(result)); if (NS_FAILED(rv)) return rv; // |lastbreak| stores the last known correct page break nsCOMPtr<nsIDOMNSHTMLElement> lastbreak; nsCOMPtr<nsIDOMNSHTMLElement> pagebreak; PRUint32 breaknum = 0; // Determine where the first adjustment needs to be made nsCOMPtr<nsIDOMNode> cursor; rv = result->IterateNext(getter_AddRefs(cursor)); while (NS_SUCCEEDED(rv) && cursor) { pagebreak = do_QueryInterface(cursor); if (pagebreak) { PRInt32 offset = 0; pagebreak->GetOffsetTop(&offset); if (breaknum >= mPageBreakOffsets.Length() || PRUint32(offset) != mPageBreakOffsets[breaknum]) break; lastbreak = pagebreak; ++breaknum; } rv = result->IterateNext(getter_AddRefs(cursor)); } if (NS_FAILED(rv)) return rv; // We're starting from scratch, might as well confirm font metrics if (! mNextPageStartsAt) CalculateFontMetrics(); // Adjust all the way to the end, or until enough time has passed if (lastbreak) { nsCOMPtr<nsIDOMNode> lastbreaknode(do_QueryInterface(lastbreak)); lastbreaknode->GetNextSibling(getter_AddRefs(cursor)); } else { nsCOMPtr<nsIDOMHTMLDocument> hdoc(do_QueryInterface(mScript)); nsCOMPtr<nsIDOMHTMLElement> body; hdoc->GetBody(getter_AddRefs(body)); body->GetFirstChild(getter_AddRefs(cursor)); } PRUint16 nodeType = 0; while (cursor) { cursor->GetNodeType(&nodeType); if (nodeType == nsIDOMNode::ELEMENT_NODE) break; nsCOMPtr<nsIDOMNode> tmp; cursor->GetNextSibling(getter_AddRefs(tmp)); cursor = tmp; } mNextPageStartsAt = cursor; mCurPageBreakNum = breaknum; nsTime start; nsTime end = start + nsTime(500000); mEditor->BeginTransaction(); while (mNextPageStartsAt && nsTime() < end) { AdjustNextPageBreak(); } mEditor->EndTransaction(); mPageCount = mPageBreakOffsets.Length() + 1; mLastPaginationEnded = nsTime(); return NS_OK; }