Qt: Fix game list settings headings not being translatable

This commit is contained in:
Connor McLaughlin 2020-08-02 03:03:25 +10:00
parent 9a9d66882c
commit 5f9481dd3d
7 changed files with 244 additions and 202 deletions

View File

@ -19,6 +19,8 @@ set(SRCS
controllersettingswidget.h
gamelistmodel.cpp
gamelistmodel.h
gamelistsearchdirectoriesmodel.cpp
gamelistsearchdirectoriesmodel.h
gamelistsettingswidget.cpp
gamelistsettingswidget.h
gamelistsettingswidget.ui

View File

@ -40,6 +40,7 @@
<ClCompile Include="audiosettingswidget.cpp" />
<ClCompile Include="consolesettingswidget.cpp" />
<ClCompile Include="gamelistmodel.cpp" />
<ClCompile Include="gamelistsearchdirectoriesmodel.cpp" />
<ClCompile Include="generalsettingswidget.cpp" />
<ClCompile Include="gpusettingswidget.cpp" />
<ClCompile Include="hotkeysettingswidget.cpp" />
@ -72,6 +73,7 @@
<QtMoc Include="qtprogresscallback.h" />
<QtMoc Include="inputbindingdialog.h" />
<QtMoc Include="gamelistmodel.h" />
<QtMoc Include="gamelistsearchdirectoriesmodel.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="settingwidgetbinder.h" />
<QtMoc Include="consolesettingswidget.h" />
@ -147,6 +149,7 @@
<ClCompile Include="$(IntDir)moc_consolesettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_controllersettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_gamelistmodel.cpp" />
<ClCompile Include="$(IntDir)moc_gamelistsearchdirectoriesmodel.cpp" />
<ClCompile Include="$(IntDir)moc_gamelistsettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_gamelistwidget.cpp" />
<ClCompile Include="$(IntDir)moc_gamepropertiesdialog.cpp" />

View File

@ -43,12 +43,14 @@
<ClCompile Include="inputbindingdialog.cpp" />
<ClCompile Include="$(IntDir)moc_inputbindingdialog.cpp" />
<ClCompile Include="gamelistmodel.cpp" />
<ClCompile Include="$(IntDir)moc_gamelistmodel.cpp" />
<ClCompile Include="gamelistsearchdirectoriesmodel.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="qtutils.h" />
<ClInclude Include="settingwidgetbinder.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="gamelistmodel.h" />
<ClInclude Include="gamelistsearchdirectoriesmodel.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="resources">
@ -81,6 +83,7 @@
<QtMoc Include="aboutdialog.h" />
<QtMoc Include="memorycardsettingswidget.h" />
<QtMoc Include="inputbindingdialog.h" />
<QtMoc Include="gamelistmodel.h" />
</ItemGroup>
<ItemGroup>
<QtUi Include="consolesettingswidget.ui" />

View File

@ -0,0 +1,178 @@
#include "gamelistsearchdirectoriesmodel.h"
#include "qthostinterface.h"
#include "qtutils.h"
#include <QtCore/QUrl>
GameListSearchDirectoriesModel::GameListSearchDirectoriesModel(QtHostInterface* host_interface)
: m_host_interface(host_interface)
{
loadFromSettings();
}
GameListSearchDirectoriesModel::~GameListSearchDirectoriesModel() = default;
int GameListSearchDirectoriesModel::columnCount(const QModelIndex& parent) const
{
if (parent.isValid())
return 0;
return 2;
}
QVariant GameListSearchDirectoriesModel::headerData(int section, Qt::Orientation orientation,
int role /*= Qt::DisplayRole*/) const
{
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
return {};
if (section == 0)
return tr("Path");
else
return tr("Recursive");
}
int GameListSearchDirectoriesModel::rowCount(const QModelIndex& parent) const
{
if (parent.isValid())
return 0;
return static_cast<int>(m_entries.size());
}
QVariant GameListSearchDirectoriesModel::data(const QModelIndex& index, int role /*= Qt::DisplayRole*/) const
{
if (!index.isValid())
return {};
const int row = index.row();
const int column = index.column();
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return {};
const Entry& entry = m_entries[row];
if (role == Qt::CheckStateRole)
{
if (column == 1)
return entry.recursive ? Qt::Checked : Qt::Unchecked;
}
else if (role == Qt::DisplayRole)
{
if (column == 0)
return entry.path;
}
return {};
}
bool GameListSearchDirectoriesModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (!index.isValid())
return false;
const int row = index.row();
const int column = index.column();
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return false;
if (column != 1 || role == Qt::CheckStateRole)
return false;
Entry& entry = m_entries[row];
entry.recursive = value == Qt::Checked;
saveToSettings();
m_host_interface->refreshGameList(false);
return true;
}
void GameListSearchDirectoriesModel::addEntry(const QString& path, bool recursive)
{
auto existing = std::find_if(m_entries.begin(), m_entries.end(), [path](const Entry& e) { return e.path == path; });
if (existing != m_entries.end())
{
const int row = static_cast<int>(existing - m_entries.begin());
existing->recursive = recursive;
dataChanged(index(row, 1), index(row, 1), QVector<int>{Qt::CheckStateRole});
}
else
{
beginInsertRows(QModelIndex(), static_cast<int>(m_entries.size()), static_cast<int>(m_entries.size()));
m_entries.push_back({path, recursive});
endInsertRows();
}
saveToSettings();
m_host_interface->refreshGameList(false);
}
void GameListSearchDirectoriesModel::removeEntry(int row)
{
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return;
beginRemoveRows(QModelIndex(), row, row);
m_entries.erase(m_entries.begin() + row);
endRemoveRows();
saveToSettings();
m_host_interface->refreshGameList(false);
}
bool GameListSearchDirectoriesModel::isEntryRecursive(int row) const
{
return (row < 0 || row >= static_cast<int>(m_entries.size())) ? false : m_entries[row].recursive;
}
void GameListSearchDirectoriesModel::setEntryRecursive(int row, bool recursive)
{
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return;
m_entries[row].recursive = recursive;
emit dataChanged(index(row, 1), index(row, 1), {Qt::CheckStateRole});
saveToSettings();
m_host_interface->refreshGameList(false);
}
void GameListSearchDirectoriesModel::openEntryInExplorer(QWidget* parent, int row) const
{
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return;
QtUtils::OpenURL(parent, QUrl::fromLocalFile(m_entries[row].path));
}
void GameListSearchDirectoriesModel::loadFromSettings()
{
std::vector<std::string> path_list = m_host_interface->GetSettingStringList("GameList", "Paths");
for (std::string& entry : path_list)
m_entries.push_back({QString::fromStdString(entry), false});
path_list = m_host_interface->GetSettingStringList("GameList", "RecursivePaths");
for (std::string& entry : path_list)
m_entries.push_back({QString::fromStdString(entry), true});
}
void GameListSearchDirectoriesModel::saveToSettings()
{
std::vector<std::string> paths;
std::vector<std::string> recursive_paths;
for (const Entry& entry : m_entries)
{
if (entry.recursive)
recursive_paths.push_back(entry.path.toStdString());
else
paths.push_back(entry.path.toStdString());
}
if (paths.empty())
m_host_interface->RemoveSettingValue("GameList", "Paths");
else
m_host_interface->SetStringListSettingValue("GameList", "Paths", paths);
if (recursive_paths.empty())
m_host_interface->RemoveSettingValue("GameList", "RecursivePaths");
else
m_host_interface->SetStringListSettingValue("GameList", "RecursivePaths", recursive_paths);
}

View File

@ -0,0 +1,41 @@
#pragma once
#include <QtCore/QAbstractTableModel>
#include <QtCore/QString>
#include <vector>
class QtHostInterface;
class GameListSearchDirectoriesModel : public QAbstractTableModel
{
Q_OBJECT
public:
GameListSearchDirectoriesModel(QtHostInterface* host_interface);
~GameListSearchDirectoriesModel();
int columnCount(const QModelIndex& parent) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex& index, const QVariant& value, int role) override;
void addEntry(const QString& path, bool recursive);
void removeEntry(int row);
bool isEntryRecursive(int row) const;
void setEntryRecursive(int row, bool recursive);
void openEntryInExplorer(QWidget* parent, int row) const;
void loadFromSettings();
void saveToSettings();
private:
struct Entry
{
QString path;
bool recursive;
};
QtHostInterface* m_host_interface;
std::vector<Entry> m_entries;
};

View File

@ -2,6 +2,7 @@
#include "common/assert.h"
#include "common/string_util.h"
#include "core/game_list.h"
#include "gamelistsearchdirectoriesmodel.h"
#include "qthostinterface.h"
#include "qtutils.h"
#include <QtCore/QAbstractTableModel>
@ -21,192 +22,6 @@
static constexpr char REDUMP_DOWNLOAD_URL[] = "http://redump.org/datfile/psx/serial,version,description";
class GameListSearchDirectoriesModel : public QAbstractTableModel
{
public:
GameListSearchDirectoriesModel(QtHostInterface* host_interface) : m_host_interface(host_interface)
{
loadFromSettings();
}
~GameListSearchDirectoriesModel() = default;
int columnCount(const QModelIndex& parent) const override
{
if (parent.isValid())
return 0;
return 2;
}
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override
{
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
return {};
if (section == 0)
return tr("Path");
else
return tr("Recursive");
}
int rowCount(const QModelIndex& parent) const override
{
if (parent.isValid())
return 0;
return static_cast<int>(m_entries.size());
}
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override
{
if (!index.isValid())
return {};
const int row = index.row();
const int column = index.column();
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return {};
const Entry& entry = m_entries[row];
if (role == Qt::CheckStateRole)
{
if (column == 1)
return entry.recursive ? Qt::Checked : Qt::Unchecked;
}
else if (role == Qt::DisplayRole)
{
if (column == 0)
return entry.path;
}
return {};
}
bool setData(const QModelIndex& index, const QVariant& value, int role) override
{
if (!index.isValid())
return false;
const int row = index.row();
const int column = index.column();
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return false;
if (column != 1 || role == Qt::CheckStateRole)
return false;
Entry& entry = m_entries[row];
entry.recursive = value == Qt::Checked;
saveToSettings();
m_host_interface->refreshGameList(false);
return true;
}
void addEntry(const QString& path, bool recursive)
{
auto existing = std::find_if(m_entries.begin(), m_entries.end(), [path](const Entry& e) { return e.path == path; });
if (existing != m_entries.end())
{
const int row = static_cast<int>(existing - m_entries.begin());
existing->recursive = recursive;
dataChanged(index(row, 1), index(row, 1), QVector<int>{Qt::CheckStateRole});
}
else
{
beginInsertRows(QModelIndex(), static_cast<int>(m_entries.size()), static_cast<int>(m_entries.size()));
m_entries.push_back({path, recursive});
endInsertRows();
}
saveToSettings();
m_host_interface->refreshGameList(false);
}
void removeEntry(int row)
{
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return;
beginRemoveRows(QModelIndex(), row, row);
m_entries.erase(m_entries.begin() + row);
endRemoveRows();
saveToSettings();
m_host_interface->refreshGameList(false);
}
bool isEntryRecursive(int row) const
{
return (row < 0 || row >= static_cast<int>(m_entries.size())) ? false : m_entries[row].recursive;
}
void setEntryRecursive(int row, bool recursive)
{
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return;
m_entries[row].recursive = recursive;
emit dataChanged(index(row, 1), index(row, 1), {Qt::CheckStateRole});
saveToSettings();
m_host_interface->refreshGameList(false);
}
void openEntryInExplorer(QWidget* parent, int row) const
{
if (row < 0 || row >= static_cast<int>(m_entries.size()))
return;
QtUtils::OpenURL(parent, QUrl::fromLocalFile(m_entries[row].path));
}
void loadFromSettings()
{
std::vector<std::string> path_list = m_host_interface->GetSettingStringList("GameList", "Paths");
for (std::string& entry : path_list)
m_entries.push_back({QString::fromStdString(entry), false});
path_list = m_host_interface->GetSettingStringList("GameList", "RecursivePaths");
for (std::string& entry : path_list)
m_entries.push_back({QString::fromStdString(entry), true});
}
void saveToSettings()
{
std::vector<std::string> paths;
std::vector<std::string> recursive_paths;
for (const Entry& entry : m_entries)
{
if (entry.recursive)
recursive_paths.push_back(entry.path.toStdString());
else
paths.push_back(entry.path.toStdString());
}
if (paths.empty())
m_host_interface->RemoveSettingValue("GameList", "Paths");
else
m_host_interface->SetStringListSettingValue("GameList", "Paths", paths);
if (recursive_paths.empty())
m_host_interface->RemoveSettingValue("GameList", "RecursivePaths");
else
m_host_interface->SetStringListSettingValue("GameList", "RecursivePaths", recursive_paths);
}
private:
struct Entry
{
QString path;
bool recursive;
};
QtHostInterface* m_host_interface;
std::vector<Entry> m_entries;
};
GameListSettingsWidget::GameListSettingsWidget(QtHostInterface* host_interface, QWidget* parent /* = nullptr */)
: QWidget(parent), m_host_interface(host_interface)
{

View File

@ -798,12 +798,12 @@
<context>
<name>GameListSearchDirectoriesModel</name>
<message>
<location filename="../gamelistsettingswidget.cpp" line="48"/>
<location filename="../gamelistsearchdirectoriesmodel.cpp" line="29"/>
<source>Path</source>
<translation>Caminho</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="50"/>
<location filename="../gamelistsearchdirectoriesmodel.cpp" line="31"/>
<source>Recursive</source>
<translation>Recursivo</translation>
</message>
@ -827,7 +827,7 @@
</message>
<message>
<location filename="../gamelistsettingswidget.ui" line="57"/>
<location filename="../gamelistsettingswidget.cpp" line="270"/>
<location filename="../gamelistsettingswidget.cpp" line="85"/>
<source>Remove</source>
<translation>Remover</translation>
</message>
@ -847,66 +847,66 @@
<translation>Atualizar Lista de Jogos</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="272"/>
<location filename="../gamelistsettingswidget.cpp" line="87"/>
<source>Open Directory...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="280"/>
<location filename="../gamelistsettingswidget.cpp" line="95"/>
<source>Select Search Directory</source>
<translation>Escolha o Diretório de Busca</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="286"/>
<location filename="../gamelistsettingswidget.cpp" line="101"/>
<source>Scan Recursively?</source>
<translation>Ler Recursivamente?</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="287"/>
<location filename="../gamelistsettingswidget.cpp" line="102"/>
<source>Would you like to scan the directory &quot;%1&quot; recursively?
Scanning recursively takes more time, but will identify files in subdirectories.</source>
<translation>Gostaria der ler o diretório recursivamente? Escanear o diretório desta forma demora mais tempo porém, identificará arquivos em sub-pastas.</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="325"/>
<location filename="../gamelistsettingswidget.cpp" line="140"/>
<source>Download database from redump.org?</source>
<translation></translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="326"/>
<location filename="../gamelistsettingswidget.cpp" line="141"/>
<source>Do you wish to download the disc database from redump.org?
This will download approximately 4 megabytes over your current internet connection.</source>
<translation>Quer baixar o banco de dados do redump? Isto significa que serão baixados 4MB de informação.</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="478"/>
<location filename="../gamelistsettingswidget.cpp" line="293"/>
<source>Downloading %1...</source>
<translation>Baixando %1...</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="478"/>
<location filename="../gamelistsettingswidget.cpp" line="293"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="489"/>
<location filename="../gamelistsettingswidget.cpp" line="304"/>
<source>Download failed</source>
<translation>Falha ao Baixar</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="496"/>
<location filename="../gamelistsettingswidget.cpp" line="311"/>
<source>Extracting...</source>
<translation>Extraindo...</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="502"/>
<location filename="../gamelistsettingswidget.cpp" line="317"/>
<source>Extract failed</source>
<translation>Falha na Extração</translation>
</message>
<message>
<location filename="../gamelistsettingswidget.cpp" line="502"/>
<location filename="../gamelistsettingswidget.cpp" line="317"/>
<source>Extracting game database failed.</source>
<translation>Extração do banco de dados falhou.</translation>
</message>