mirror of
https://invent.kde.org/marcoa/a-la-karte.git
synced 2026-02-09 21:13:08 +00:00
Fix library persistence and duplicate handling
Ensure persistence operates on the full game list, not filtered rows. Deduplicate imported entries by stable game ID to prevent missing games and regressions when importing from multiple sources.
This commit is contained in:
parent
e468f53c91
commit
58f69e6717
3 changed files with 162 additions and 9 deletions
158
src/app.cpp
158
src/app.cpp
|
|
@ -179,6 +179,156 @@ void App::importAllGames()
|
|||
Qt::QueuedConnection);
|
||||
totalCount += heroicGames.count();
|
||||
|
||||
// Import from Desktop entries
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() {
|
||||
setImportStatus(tr("Scanning desktop entries..."));
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
DesktopImporter desktopImporter;
|
||||
QList<Game *> desktopGames = desktopImporter.importGames();
|
||||
for (Game *game : desktopGames) {
|
||||
game->moveToThread(this->thread());
|
||||
game->setParent(nullptr);
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, desktopGames]() {
|
||||
for (Game *game : desktopGames) {
|
||||
m_gameModel->addGame(game);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
totalCount += desktopGames.count();
|
||||
|
||||
// Import from Bottles
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() {
|
||||
setImportStatus(tr("Scanning Bottles..."));
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
BottlesImporter bottlesImporter;
|
||||
QList<Game *> bottlesGames = bottlesImporter.importGames();
|
||||
for (Game *game : bottlesGames) {
|
||||
game->moveToThread(this->thread());
|
||||
game->setParent(nullptr);
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, bottlesGames]() {
|
||||
for (Game *game : bottlesGames) {
|
||||
m_gameModel->addGame(game);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
totalCount += bottlesGames.count();
|
||||
|
||||
// Import from Flatpak
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() {
|
||||
setImportStatus(tr("Scanning Flatpak games..."));
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
FlatpakImporter flatpakImporter;
|
||||
QList<Game *> flatpakGames = flatpakImporter.importGames();
|
||||
for (Game *game : flatpakGames) {
|
||||
game->moveToThread(this->thread());
|
||||
game->setParent(nullptr);
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, flatpakGames]() {
|
||||
for (Game *game : flatpakGames) {
|
||||
m_gameModel->addGame(game);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
totalCount += flatpakGames.count();
|
||||
|
||||
// Import from itch.io
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() {
|
||||
setImportStatus(tr("Scanning itch.io library..."));
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
ItchImporter itchImporter;
|
||||
QList<Game *> itchGames = itchImporter.importGames();
|
||||
for (Game *game : itchGames) {
|
||||
game->moveToThread(this->thread());
|
||||
game->setParent(nullptr);
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, itchGames]() {
|
||||
for (Game *game : itchGames) {
|
||||
m_gameModel->addGame(game);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
totalCount += itchGames.count();
|
||||
|
||||
// Import from Legendary
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() {
|
||||
setImportStatus(tr("Scanning Legendary library..."));
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
LegendaryImporter legendaryImporter;
|
||||
QList<Game *> legendaryGames = legendaryImporter.importGames();
|
||||
for (Game *game : legendaryGames) {
|
||||
game->moveToThread(this->thread());
|
||||
game->setParent(nullptr);
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, legendaryGames]() {
|
||||
for (Game *game : legendaryGames) {
|
||||
m_gameModel->addGame(game);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
totalCount += legendaryGames.count();
|
||||
|
||||
// Import from RetroArch
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() {
|
||||
setImportStatus(tr("Scanning RetroArch playlists..."));
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
RetroArchImporter retroArchImporter;
|
||||
QList<Game *> retroArchGames = retroArchImporter.importGames();
|
||||
for (Game *game : retroArchGames) {
|
||||
game->moveToThread(this->thread());
|
||||
game->setParent(nullptr);
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, retroArchGames]() {
|
||||
for (Game *game : retroArchGames) {
|
||||
m_gameModel->addGame(game);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
totalCount += retroArchGames.count();
|
||||
|
||||
// Complete
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
|
|
@ -490,8 +640,8 @@ void App::removeMissingGames()
|
|||
{
|
||||
QList<Game *> gamesToRemove;
|
||||
|
||||
for (int i = 0; i < m_gameModel->rowCount(); ++i) {
|
||||
Game *game = m_gameModel->gameAt(i);
|
||||
const QList<Game *> games = m_gameModel->allGames();
|
||||
for (Game *game : games) {
|
||||
if (!game)
|
||||
continue;
|
||||
|
||||
|
|
@ -552,8 +702,8 @@ void App::saveLibrary()
|
|||
}
|
||||
|
||||
QJsonArray gamesArray;
|
||||
for (int i = 0; i < m_gameModel->rowCount(); ++i) {
|
||||
Game *game = m_gameModel->gameAt(i);
|
||||
const QList<Game *> games = m_gameModel->allGames();
|
||||
for (Game *game : games) {
|
||||
if (game) {
|
||||
gamesArray.append(game->toJson());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ void GameModel::addGame(Game *game)
|
|||
|
||||
// Check for duplicates
|
||||
for (Game *existing : m_games) {
|
||||
if (existing->platform() == game->platform() && existing->platformId() == game->platformId()) {
|
||||
if (existing->id() == game->id()) {
|
||||
delete game;
|
||||
return;
|
||||
}
|
||||
|
|
@ -209,12 +209,8 @@ void GameModel::addGame(Game *game)
|
|||
|
||||
game->setParent(this);
|
||||
|
||||
beginInsertRows(QModelIndex(), m_games.count(), m_games.count());
|
||||
m_games.append(game);
|
||||
endInsertRows();
|
||||
|
||||
applyFilter();
|
||||
Q_EMIT countChanged();
|
||||
}
|
||||
|
||||
void GameModel::removeGame(const QString &id)
|
||||
|
|
@ -275,6 +271,11 @@ QStringList GameModel::platforms() const
|
|||
return result;
|
||||
}
|
||||
|
||||
QList<Game *> GameModel::allGames() const
|
||||
{
|
||||
return m_games;
|
||||
}
|
||||
|
||||
bool GameModel::matchesFilter(Game *game) const
|
||||
{
|
||||
if (!m_showHidden && game->hidden()) {
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ public:
|
|||
Q_INVOKABLE void clear();
|
||||
Q_INVOKABLE QStringList platforms() const;
|
||||
|
||||
QList<Game *> allGames() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void countChanged();
|
||||
void filterTextChanged();
|
||||
|
|
|
|||
Loading…
Reference in a new issue