Merge pull request #7455 from spycrab/qt_tags

Qt/GameList: Implement tag system
This commit is contained in:
Pierre Bourdon 2018-10-13 19:58:32 +02:00 committed by GitHub
commit 2bdee9b80b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 146 additions and 2 deletions

View File

@ -201,6 +201,7 @@ void SConfig::SaveGameListSettings(IniFile& ini)
gamelist->Set("ColumnID", m_showIDColumn); gamelist->Set("ColumnID", m_showIDColumn);
gamelist->Set("ColumnRegion", m_showRegionColumn); gamelist->Set("ColumnRegion", m_showRegionColumn);
gamelist->Set("ColumnSize", m_showSizeColumn); gamelist->Set("ColumnSize", m_showSizeColumn);
gamelist->Set("ColumnTags", m_showTagsColumn);
} }
void SConfig::SaveCoreSettings(IniFile& ini) void SConfig::SaveCoreSettings(IniFile& ini)
@ -475,6 +476,7 @@ void SConfig::LoadGameListSettings(IniFile& ini)
gamelist->Get("ColumnID", &m_showIDColumn, false); gamelist->Get("ColumnID", &m_showIDColumn, false);
gamelist->Get("ColumnRegion", &m_showRegionColumn, true); gamelist->Get("ColumnRegion", &m_showRegionColumn, true);
gamelist->Get("ColumnSize", &m_showSizeColumn, true); gamelist->Get("ColumnSize", &m_showSizeColumn, true);
gamelist->Get("ColumnTags", &m_showTagsColumn, false);
} }
void SConfig::LoadCoreSettings(IniFile& ini) void SConfig::LoadCoreSettings(IniFile& ini)

View File

@ -270,6 +270,7 @@ struct SConfig
bool m_showIDColumn; bool m_showIDColumn;
bool m_showRegionColumn; bool m_showRegionColumn;
bool m_showSizeColumn; bool m_showSizeColumn;
bool m_showTagsColumn;
std::string m_WirelessMac; std::string m_WirelessMac;
bool m_PauseMovie; bool m_PauseMovie;

View File

@ -14,6 +14,7 @@
#include <QFileInfo> #include <QFileInfo>
#include <QFrame> #include <QFrame>
#include <QHeaderView> #include <QHeaderView>
#include <QInputDialog>
#include <QKeyEvent> #include <QKeyEvent>
#include <QLabel> #include <QLabel>
#include <QListView> #include <QListView>
@ -132,6 +133,7 @@ void GameList::MakeListView()
hor_header->setSectionResizeMode(GameListModel::COL_COUNTRY, QHeaderView::Fixed); hor_header->setSectionResizeMode(GameListModel::COL_COUNTRY, QHeaderView::Fixed);
hor_header->setSectionResizeMode(GameListModel::COL_SIZE, QHeaderView::Fixed); hor_header->setSectionResizeMode(GameListModel::COL_SIZE, QHeaderView::Fixed);
hor_header->setSectionResizeMode(GameListModel::COL_FILE_NAME, QHeaderView::Interactive); hor_header->setSectionResizeMode(GameListModel::COL_FILE_NAME, QHeaderView::Interactive);
hor_header->setSectionResizeMode(GameListModel::COL_TAGS, QHeaderView::Interactive);
// There's some odd platform-specific behavior with default minimum section size // There's some odd platform-specific behavior with default minimum section size
hor_header->setMinimumSectionSize(38); hor_header->setMinimumSectionSize(38);
@ -174,6 +176,7 @@ void GameList::UpdateColumnVisibility()
m_list->setColumnHidden(GameListModel::COL_SIZE, !SConfig::GetInstance().m_showSizeColumn); m_list->setColumnHidden(GameListModel::COL_SIZE, !SConfig::GetInstance().m_showSizeColumn);
m_list->setColumnHidden(GameListModel::COL_FILE_NAME, m_list->setColumnHidden(GameListModel::COL_FILE_NAME,
!SConfig::GetInstance().m_showFileNameColumn); !SConfig::GetInstance().m_showFileNameColumn);
m_list->setColumnHidden(GameListModel::COL_TAGS, !SConfig::GetInstance().m_showTagsColumn);
} }
void GameList::MakeEmptyView() void GameList::MakeEmptyView()
@ -336,6 +339,35 @@ void GameList::ShowContextMenu(const QPoint&)
menu->addAction(tr("Open &containing folder"), this, &GameList::OpenContainingFolder); menu->addAction(tr("Open &containing folder"), this, &GameList::OpenContainingFolder);
menu->addAction(tr("Delete File..."), this, &GameList::DeleteFile); menu->addAction(tr("Delete File..."), this, &GameList::DeleteFile);
menu->addSeparator();
auto* model = Settings::Instance().GetGameListModel();
auto* tags_menu = menu->addMenu(tr("Tags"));
auto path = game->GetFilePath();
auto game_tags = model->GetGameTags(path);
for (const auto& tag : model->GetAllTags())
{
auto* tag_action = tags_menu->addAction(tag);
tag_action->setCheckable(true);
tag_action->setChecked(game_tags.contains(tag));
connect(tag_action, &QAction::toggled, this, [this, path, tag, model](bool checked) {
if (!checked)
model->RemoveGameTag(path, tag);
else
model->AddGameTag(path, tag);
});
}
menu->addAction(tr("New Tag..."), this, &GameList::NewTag);
menu->addAction(tr("Remove Tag..."), this, &GameList::DeleteTag);
menu->addSeparator();
QAction* netplay_host = new QAction(tr("Host with NetPlay"), menu); QAction* netplay_host = new QAction(tr("Host with NetPlay"), menu);
connect(netplay_host, &QAction::triggered, [this, game] { connect(netplay_host, &QAction::triggered, [this, game] {
@ -742,7 +774,8 @@ void GameList::OnColumnVisibilityToggled(const QString& row, bool visible)
{tr("File Name"), GameListModel::COL_FILE_NAME}, {tr("File Name"), GameListModel::COL_FILE_NAME},
{tr("Game ID"), GameListModel::COL_ID}, {tr("Game ID"), GameListModel::COL_ID},
{tr("Region"), GameListModel::COL_COUNTRY}, {tr("Region"), GameListModel::COL_COUNTRY},
{tr("File Size"), GameListModel::COL_SIZE}}; {tr("File Size"), GameListModel::COL_SIZE},
{tr("Tags"), GameListModel::COL_TAGS}};
m_list->setColumnHidden(rowname_to_col_index[row], !visible); m_list->setColumnHidden(rowname_to_col_index[row], !visible);
} }
@ -859,6 +892,26 @@ void GameList::OnHeaderViewChanged()
block = false; block = false;
} }
void GameList::NewTag()
{
auto tag = QInputDialog::getText(this, tr("New tag"), tr("Name for a new tag:"));
if (tag.isEmpty())
return;
Settings::Instance().GetGameListModel()->NewTag(tag);
}
void GameList::DeleteTag()
{
auto tag = QInputDialog::getText(this, tr("Remove tag"), tr("Name of the tag to remove:"));
if (tag.isEmpty())
return;
Settings::Instance().GetGameListModel()->DeleteTag(tag);
}
void GameList::SetSearchTerm(const QString& term) void GameList::SetSearchTerm(const QString& term)
{ {
m_model->SetSearchTerm(term); m_model->SetSearchTerm(term);

View File

@ -60,6 +60,8 @@ private:
void ExportWiiSave(); void ExportWiiSave();
void CompressISO(bool decompress); void CompressISO(bool decompress);
void ChangeDisc(); void ChangeDisc();
void NewTag();
void DeleteTag();
void UpdateColumnVisibility(); void UpdateColumnVisibility();
void ZoomIn(); void ZoomIn();

View File

@ -42,6 +42,11 @@ GameListModel::GameListModel(QObject* parent) : QAbstractTableModel(parent)
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
emit layoutChanged(); emit layoutChanged();
}); });
auto& settings = Settings::GetQSettings();
m_tag_list = settings.value(QStringLiteral("gamelist/tags")).toStringList();
m_game_tags = settings.value(QStringLiteral("gamelist/game_tags")).toMap();
} }
QVariant GameListModel::data(const QModelIndex& index, int role) const QVariant GameListModel::data(const QModelIndex& index, int role) const
@ -117,6 +122,14 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
if (role == Qt::InitialSortOrderRole) if (role == Qt::InitialSortOrderRole)
return static_cast<quint64>(game.GetFileSize()); return static_cast<quint64>(game.GetFileSize());
break; break;
case COL_TAGS:
if (role == Qt::DisplayRole || role == Qt::InitialSortOrderRole)
{
auto tags = GetGameTags(game.GetFilePath());
tags.sort();
return tags.join(QStringLiteral(", "));
}
} }
return QVariant(); return QVariant();
@ -143,6 +156,8 @@ QVariant GameListModel::headerData(int section, Qt::Orientation orientation, int
return tr("File Name"); return tr("File Name");
case COL_SIZE: case COL_SIZE:
return tr("Size"); return tr("Size");
case COL_TAGS:
return tr("Tags");
} }
return QVariant(); return QVariant();
} }
@ -293,3 +308,57 @@ float GameListModel::GetScale() const
{ {
return m_scale; return m_scale;
} }
const QStringList& GameListModel::GetAllTags() const
{
return m_tag_list;
}
const QStringList GameListModel::GetGameTags(const std::string& path) const
{
return m_game_tags[QString::fromStdString(path)].toStringList();
}
void GameListModel::AddGameTag(const std::string& path, const QString& name)
{
auto tags = GetGameTags(path);
if (tags.contains(name))
return;
tags << name;
m_game_tags[QString::fromStdString(path)] = tags;
Settings::GetQSettings().setValue(QStringLiteral("gamelist/game_tags"), m_game_tags);
}
void GameListModel::RemoveGameTag(const std::string& path, const QString& name)
{
auto tags = GetGameTags(path);
tags.removeAll(name);
m_game_tags[QString::fromStdString(path)] = tags;
Settings::GetQSettings().setValue(QStringLiteral("gamelist/game_tags"), m_game_tags);
}
void GameListModel::NewTag(const QString& name)
{
if (m_tag_list.contains(name))
return;
m_tag_list << name;
Settings::GetQSettings().setValue(QStringLiteral("gamelist/tags"), m_tag_list);
}
void GameListModel::DeleteTag(const QString& name)
{
m_tag_list.removeAll(name);
for (const auto& file : m_game_tags.keys())
RemoveGameTag(file.toStdString(), name);
Settings::GetQSettings().setValue(QStringLiteral("gamelist/tags"), m_tag_list);
}

View File

@ -8,7 +8,10 @@
#include <string> #include <string>
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QMap>
#include <QString> #include <QString>
#include <QStringList>
#include <QVariant>
#include "Core/TitleDatabase.h" #include "Core/TitleDatabase.h"
@ -52,6 +55,7 @@ public:
COL_COUNTRY, COL_COUNTRY,
COL_SIZE, COL_SIZE,
COL_FILE_NAME, COL_FILE_NAME,
COL_TAGS,
NUM_COLS NUM_COLS
}; };
@ -62,10 +66,22 @@ public:
void SetScale(float scale); void SetScale(float scale);
float GetScale() const; float GetScale() const;
const QStringList& GetAllTags() const;
const QStringList GetGameTags(const std::string& path) const;
void AddGameTag(const std::string& path, const QString& name);
void RemoveGameTag(const std::string& path, const QString& name);
void NewTag(const QString& name);
void DeleteTag(const QString& name);
private: private:
// Index in m_games, or -1 if it isn't found // Index in m_games, or -1 if it isn't found
int FindGame(const std::string& path) const; int FindGame(const std::string& path) const;
QStringList m_tag_list;
QMap<QString, QVariant> m_game_tags;
GameTracker m_tracker; GameTracker m_tracker;
QList<std::shared_ptr<const UICommon::GameFile>> m_games; QList<std::shared_ptr<const UICommon::GameFile>> m_games;
Core::TitleDatabase m_title_database; Core::TitleDatabase m_title_database;

View File

@ -570,7 +570,8 @@ void MenuBar::AddListColumnsMenu(QMenu* view_menu)
{tr("File Name"), &SConfig::GetInstance().m_showFileNameColumn}, {tr("File Name"), &SConfig::GetInstance().m_showFileNameColumn},
{tr("Game ID"), &SConfig::GetInstance().m_showIDColumn}, {tr("Game ID"), &SConfig::GetInstance().m_showIDColumn},
{tr("Region"), &SConfig::GetInstance().m_showRegionColumn}, {tr("Region"), &SConfig::GetInstance().m_showRegionColumn},
{tr("File Size"), &SConfig::GetInstance().m_showSizeColumn}}; {tr("File Size"), &SConfig::GetInstance().m_showSizeColumn},
{tr("Tags"), &SConfig::GetInstance().m_showTagsColumn}};
QActionGroup* column_group = new QActionGroup(this); QActionGroup* column_group = new QActionGroup(this);
QMenu* cols_menu = view_menu->addMenu(tr("List Columns")); QMenu* cols_menu = view_menu->addMenu(tr("List Columns"));