Previously the `setGeometry()` method was called explicitly. In this
procedure the self-centering widget installs an `eventFilter` on its
parent to react to `Resize` events of the parent.
This breaks centering on the list widgets a bit, pending an investigation
Also partition the space to left and right layouts, left layout being the
image and the space below it (pending future usage), and right the
information.
CloudSaves: don't save `save_path` in case it hasn't changed
IconGameWidget/ListGameWidget: Remove dead code
RareCore: add string translations
utils/paths: Use `AppDataLocation` instead of deprecated `DataLocation`
This allows to complete from relative paths, such use exe override
Fix constructor argument names to follow Qt's types.
Set the same filters as the dialog for the completer.
Use the completer's icon provider for the dialog.
Force Rare to use Qt's file dialog instead of the native one.
When importing a game, the first thing being checked for import information
is `<install_dir>/.egstore`. Due to erroneous handling, that directory can
contain multiples of `.mancpn` and `.manifest` files. This could lead to
importing an older version as legendary expects only one pair of these
files to exist in that directory.
The `.egstore` folder is normally updated/created as part of synchronizing
with EGL. To aid with importing games in the future, we always export this
data for Rare to be able to import games between different OSes
- Show text on widget if save is not up-to-date
- Fix text in game info -> cloud saves
Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
This is the last change of the `backend_refactor` branch. This makes
`RareCore` the centerpiece of Rare by moving initialization before the UI
is brought up. RareCore is now in control of creating and querying `RareGame`
objects, re-introducing the ability (incomplete) to refresh the games library.
As a result, ApiResults has been removed.
Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
When the button gets clicked on, it receives keyboard focus. Disabling the button
afterwards leads to `focusNextChild` getting called. This makes the scrollarea
trying to ensure that `nextChild` is visible, essentially scrolling to a random widget
The static stylesheet properties are always applied. If there is a theme
stylesheet to be applied, they are appended in the end of the theme
stylesheet.
This removes stylesheet properties from the library widgets, some special
buttons and the queue worker labels.
To update the static stylesheet first edit `rare/resources/static_css/stylesheet.py`
and then execute it as a script.
Widgets that need to implement a title should be of a dual subclass
of any `QWidget` subclass and the `SideTabContents` class which provides
the signal.
Word wrapping allows ElideLabel to resize first inside flexible sized
areas such as the contents widget of a scrollarea. This allows the contents
widget to properly resize itself to avoid horizontal scrolling.
Word-wrapping also enables the widget to resize vertically. To avoid that
ElideLabel is set to a fixed height based on font metrics. An overloaded
method `setFixedHeight` has been added to disable it when desired.
EglSyncGroup: Replace estimated path label with a ElideLabel because
the displayed message was expanding the scrollarea.
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()
```
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.
They are used to insert and remove updates from downloads when
the installation of a game changes through `RareGame.set_installed`.
They piggy-back the signals with the same names in `GlobalSignals`
When importing a game from EGL, also check
By using a QToolBox, we can better utilize the available space for
long lists of DLCs. `GameDlcWidget` is now responsible for handling
installing and uninstalling the DLC based on RareGame's functionality.
Since `GameUtils` is not used for uninstalling any more, remove it the
arguments of `GameInfoTabs` completely.
The `objectName()` of onstall and uninstall buttons should be set
to `InstallButton` and `UninstallButton` respectively for them to
pick up their special CSS properties.
Make QToolBox tab text bold
Clean-up deprecated widget object names in the CSS
Similarly to the installation procedure, when an uninstall is
requested, an `UninstallOptionsModel` is emitted by the `RareGame`.
`DownloadsTab` handles the signal and spawns the `UninstallDialog`.
After the `UninstallDialog` is closed, a worker thread handles
uninstalling the application to avoid UI lock-ups when a large
number of files is deleted.
Allows for uninstall actions to be spawned from anything having
access to the `RareGame` instance.
LaunchDialog: Don't check health on DLCs, they always will require
verification if they don't specify an executable.
Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
instead of adding them again to the layout. Move game should still
switch to RareGame, similar to the way it works for verifing.
Also add non-functional "Import Game" button
Also remove attributes tracking the state of each application, those
are handled by `RareGame`
Temporarily disable save syncing related code, pending the move to
the game launcher process
When `Uninstall` is used from the widgets, it will take the user to
the `GameInfo` page similar to how `Install` works.
`GameInfo` is not connected to the `RareGame` instance's `installed`
and `uninstalled` signals to refresh the contents of the page based
on the related functionality.
When updates are queued, they are removed from the update's list. An exceptions is made
when the queued item comes from repairing (without updating), in which case the update is
disabled for the runtime.
A queued item can be either removed (if it is an update it will be added back to the
updates groups) or forced to be updated now. If a queued item is forced, the currently
running item will be added to the front of the queue. Downloads will be queued if
there is no active download but there is a queue already.
The download thread is now responsible for emitting the progress to `RareGame`
InstallDialog: Pass `RareGame` and `InstallOptionsModel` only as arguments.
The `update`, `repair` and `silent` arguments are already part of `InstallOptionsModel`
`RareGame` is used to query information about the game.
InstallInfoWorker: Pass only `InstallOptionsModel` as argument
Emit `InstallQueueItemModel` as result, to re-use the worker when queuing stopped games
RareGame: Query and store metadata property about entitlement grant date
RareGame: Add `RareEosOverlay` class that imitates `RareGame` to handle the overlay
LibraryWidgetController: Remove dead signal routing code, these signals are handled by `RareGame`
Directly parent library widgets instead of reparenting them
GameWidgets: Remove unused signals
EOSGroup: Set install location based on preferences and use EOSOverlayApp from legendary
GamesTab: Connect the `progress` signals of dlcs to the base game's signals
GamesTab: Remove dead code
GlobalSignals: Remove `ProgresSignals`
RareCore: Mangle internal signleton's names
Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
Subclass `EGLSyncListGroup` and `EGLSyncListItem` into import/export
specific classes. This way we don't have to specify the type of
operation at instatiation and improves code clarity and intention.
Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
The `GameProcess` class now acts as a persistent member of `RareGame`
that can be re-used for launching games. Its signals are handled and
repeated by `RareGame`.
Implements launching directly into `RareGame`
Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
This merges a few of the internal features of RareCore such us
RareGame filtering and thus game grouping based on attributes.
This is required to properly connect a single signal from RareCore to
the downloads tab for game installation. This also includes filtering
games based on updates and other attributes.
Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
The original status_label is used to reflect the state of the game,
the tooltip_label is used to reflect the action of the current hovered
widget.
Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>