Disable commenting when there's a pending draft of a review request.

A common mistake is to put up a new diff or file attachment and then try
to comment on it before publishing the draft. This doesn't work, and
will fail on an API level, but we didn't tell the user at any point that
they should expect problems doing that.

Now, the dialog will tell the user they must publish before they can
comment on the diff or file. All the fields will be disabled.

Note that bug #831 requests that we *allow* commenting. That's a much
bigger problem to solve, and one we won't be solving as part of this
change. This just fixes the unexpected failure case.
Improve file attachment comment links.

The file attachment comments in reviews had a link which looks similar to diff
comments. The text of this link is the filename, and the destination was the
download URL.

In the case where the attachment has a review UI, we want the link target to be
the review UI instead of the download URL. This change adds that in (with the
ability for the review UI to customize the link, for example, to link to a
specific page). This also includes some code for the review UI to customize the
text of the link, for example, to list which page the comment is on.

Testing done: Tested this in conjunction with our premium pdf review UI.

Reviewed at http://reviews.reviewboard.org/r/4148/
Improve file attachment comments in review emails.

Comments for file attachments in review emails were kind of crummy. They'd show
either the caption or the filename (unlike the web UI, which showed both). They
linked to the download URL, even when there was a review UI. And finally, they
wouldn't show comment thumbnails.

Testing done:
Set up a review and a reply and checked out the preview-email URLs.

Reviewed at http://reviews.reviewboard.org/r/4149/
Update the docs database.
Refactor our per-file diff rendering code into a DiffRenderer class.

DiffRenderer is responsible for taking the output of get_diff_files, and
some configuration (highlighting, collapse state, etc.) and rendering
diff output. It separates out the various responsibilities of the old
function, such as computing the cache key and rendering to strings and
HttpResponses.

There's one DiffRenderer per thing to render. It's created, used, and
thrown away.

A DiffRenderer is accessed by get_diff_renderer or
get_diff_renderer_class, rather than relying on using DiffRenderer
directly, allowing for some extensibility.

The new tests rely on kgb for function spies.
Merge branch 'release-1.7.x'