Non-blocking content-assist in FetchGerritChangePage
Perform the underlying git ls-remote command used to fetch the
refs for the content assist on the "Change" field in the background.
A normal WizardDialog does not support this; its run() method always
disables the dialog and uses a ModalContext to run the Runnable.
Therefore, extend WizardDialog to really run Runnables in the
background if fork == true. The dialog remains active while the job
is running. Background jobs are canceled if the dialog is closed (or
the wizard page is changed) before they have terminated.
Rewrite the FetchGerritChangePage to take that into account.
Implement ChangeLists as Futures; pre-fetch them to minimize the
perceived waiting time for the user when content assist is invoked,
and rewrite the content proposal provider to use these futures. If
not completed yet, return null (no proposals, and no beep either),
but once available and the uri is still the same, do pop up the
proposals if the focus is still in the Change field.
There are actually two new layers of jobs in this implementation.
First the BackgroundJobs in the new NonBlockingWizardDialog. Those
take care of performing some true background work while still being
able to report progress through the wizard's progress monitor in the
UI. Second, the jobs used by the ChangeList futures. Those have three
purposes:
* They enable pre-fetching.
* They encapsulate the logic of starting and canceling jobs
* The de-coupling makes it possible to cancel the BackgroundJob
visible in the UI while still keeping on getting the result so
that it will be available in the future if content assist is
invoked again.
Because it is now possible to enter a branch name while the content
proposal is in progress, only update the branch (and tag) name if
the user did not edit it or if it is empty. (That already occurred
before this change, but probably rarely since people typically fill
out the dialog from the top: enter change number, invoke content
assist, select patch set, then perhaps go edit the suggested branch
name. With asynchronous content assist and the dialog not blocked,
the sequence enter change number, invoke content assist (may take
a while, especially the first time), enter branch name, invoke content
assist again, select patch set is more likely to occur making this
overwriting of a user-supplied branch name more of a noticeable
nuisance.)
Overall I find:
* The pre-fetch does reduce the time for the first content assist in
many cases. It doesn't help much if the clipboard contains content
we use to auto-fill the Change field and invoke the content assist
directly.
* The dialog not being blocked, the time spent fetching the refs can
be used to enter the branch name already.
* The new background jobs make it possible to cancel the dialog when
fetching the refs takes long and is still in progress. Previously,
one had to wait until that was done, and it couldn't be canceled
either.
Note that the FetchGerritChangePage also still works when run inside
a normal WizardDialog that does not support background operations.
This is a service to the Egerrit project; they use this (EGit-
internal!) wizard. The only benefit is then the pre-fetch.
Bug: 515733
Change-Id: I7626d8092ba6ea35a6761e167c5e9227448cc565
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>