widgets.diff: add DiffEditor.has_selection()

This new method is a cheaper alternative to
DiffEditor.offset_and_selection() if the actual content of the selection
is not needed.

Signed-off-by: Daniel Harding <dharding@living180.net>
widgets.diff: simplify if logic

Pull a repeated check for s.modified up into the parent if statement.

Signed-off-by: Daniel Harding <dharding@living180.net>
widgets.diff: improve offset_and_selection method

In the DiffEditor.offset_and_selection() method, use
cursor.selectionStart() instead of cursor.position() because
cursor.position() can be at either end of the selection.

Signed-off-by: Daniel Harding <dharding@living180.net>
widgets.diff: simplify stage/unstage/revert

Previously the Stage, Unstage, and Revert commands each had two
variants, e.g. "Stage Diff Hunk" and "Stage Selected Lines".  The "Diff
Hunk" variant would act upon the hunk underneath the cursor if there was
no selection, or on all hunks falling within the selection if there was
a selection.  The "Selected Lines" variant was only enabled if there was
a selection and would operate on the lines falling within the selection.

It was decided to simplify things and combine the two variants into a
single command that adapts to the context.  Returning to the "Stage"
case, the command stages the hunk under the cursor if there is no
selection, and stages the selected lines if there is a selection.

This was actually implemented by making a single context-sensitive
action for the Stage/Unstage case, and another action for the Revert
case.  The action text (and icon, for the Stage/Unstage action) is set
dynamically when creating the context menu.

Closes #330

Suggested-by: Uri Okrent <uokrent@gmail.com>
Helped-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Daniel Harding <dharding@living180.net>
Merge pull request #333 from living180/issue_330

widgets.diff: improve stage and revert actions

Closes #330

Signed-off-by: David Aguilar <davvid@gmail.com>