Execute the edit callback function in a thread. By executing it in a thread
we don't have to wait for longer validation procedures to finish to
continue updating the UI. This is most notable in the MoveGamePopUp
which is heavy on disk IO.
Because we cannot use special text formatting in a thread, the
indicator messages have been reworked while also becoming extensible.
A dictionary of extended reasons can be specified through the
`IndicatorLineEdit.extend_reasons()` method.
The dictionary has to follow the following format
```
python
{
MyIndicatorReasons.REASON: self.tr("Reason message")
MyIndicatorReasons.OTHER_REASON: self.tr("Other reason message")
}
```
In the above example `MyIndicatorReasons` is a subclass of `IndicatorReasons`
which should be specified as follows
```
python
MyIndicatorReasons(IndicatorReasons):
REASON = auto()
OTHER_REASON = auto()
```
There are DLCs (for example KingletAztec) which are essentially
entitlements, a single file the allows access to already downloaded
content. Updates for such DLCs only change the metadata version number
without any actual new data. These DLCs are handled correctly by the
DLM, but our dialog would refuse to allow installing them due to 0 download
size. This change allows them to pass through the InstallDialog.
The other issue, which I don't know if it was only a result of our faulty
validation at startup or could occur in legendary too, is that a DLC might
be marked with needing verification. Currently we don't have a way of
verifying DLCs, so when verifying the game, we will also set the same
state for any installed DLCs. In effect verifying the game successfully
will also mark any DLCs as correct.
The active workers are placed in a static container on the left side.
The queued workers are placed in a scrollarea on the right side of the
status bar. The scrollbars are disabled but dragging works.
Exiting with active workers will pop up a message for confirmation. Rare
will clean the queued workers but the active ones will be waited on until
they finish.
Note: the `__update_widget()` method, while it doesn't have any visible delay
has the potential for improvement. I didn't do it because it felt like
premature optimization.
MoveGamePopUp: update it to use RareGame and it's signals
RareGame: Add `install_path` attribute and change `needs_verification` setter
Now both setters will update the local `igame` attribute and save it too.
MoveWorker: Update it to use RareGame.
Other changes include moving "same-drive" moving into the worker and using
`os.path` methods instead of `PathLib`
SteamGrades: Remove worker, it is implemented in RareGame now.
The `status_label` displays what is currently going on with the game.
It reflects the current operation running on it or if it requires special
attention (update, needs verification etc)
The `tooltip_label` displays hover information such as what happens
if a part of the widget is clicked or in the case of the launch button if
the game can run (without version check, offline etc)
The context menu on the widgets will be updated and populated according
to the installation state of the game. Since the context menu was revised
the shortcut creation code was revised too to make it more compact.
the `create_desktop_link` and `get_rare_executable` functions are moved
from `rare.utils.misc` to `rare.utils.paths` to avoid cyclical imports and
better grouping. Two functions are added, `desktop_link_path` to uniformly
calculate the path of the shortcut and `desktop_links_supported` which
checks if Rare supports creating shortcuts on the current platform.
`desktop_links_supported` should be used as safeguard before `desktop_link_path`.
Desktop links are currently untested on Windows but if `shortcut.Description`
works as expected, it should be good to go.
`LegendaryCore.get_non_asset_library_items()` returns the same tuple
for `game_list, dlc_dict` as for regular games with assets, so
keep the result for API completeness, since `RareGame` can handle those
games properly.