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);
}
예제 #3
0
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;
}
예제 #4
0
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;
}