* We forward a different range of ports to each device so we can pick
and choose which to communicate with based on its index.
* The index is encoded in the 'hostname' like so: adb:X:deviceidhere
* Whenever we want to interact with an android device we always specify
the device, never leave it to a default.
* Instead of having button enabling and so on logic in both
on_hostname_textEdited and on_hosts_itemClicked, just handle the
hostname edit as selection or unselecting any matching item, and then
process all the logic whenever the selection changes.
* Checking for a NULL parent item doesn't work, the parent will be the
invisible root item.
* Also make sure we don't delete a host that might have enumerations
still going for it.
* This was only added because the default tree widget controls don't
render any grid lines. Now that we're custom drawing them, the row
colors are distracting and can be confusing on themes where the
selected row is very faint.
* Any work that might use Qt needs to happen on the UI thread, so when
running a python script on the python thread we need to invoke across.
We wrap the main ICaptureContext interface to block invoke onto the UI
for any function calls that aren't just returning internal data.
* QShortcut falls down on duplicates. It can have activatedAmbiguously
events, but these happen in arbitrary order and the shortcuts on
menu items just swallow the ambiguous activate so it's not useful.
* Instead we just let MainWindow pick up ShortcutOverride events and
consult a mapping of which shortcuts to use. We can use a smarter
selection method to choose the more 'local' shortcut if two shortcuts
that conflict exist.
There are a few places where the logical 'and' operator
was used to check if a given flag is enabled however
that is not the correct operator.
The binary 'and' operator should be used where
the enum acts as a flag.
* Annoyingly although Qt has an internal bool allowUserMoveOfSection0
which does exactly what we want allowing the tree column to be
movable, we can't enable it because it's private. So instead we have
to re-implement section moving ourselves.
* Minor tweak - also made RDTreeWidgets non-movable by default since
usually we don't want to allow it.
* When we add it, if a log is already open that's when we get the
callback to OnLogFileOpened to initialised. If we close afterwards,
we'll be in an inconsistent state.