Merge pull request #7455 from spycrab/qt_tags
Qt/GameList: Implement tag system
This commit is contained in:
commit
2bdee9b80b
|
@ -201,6 +201,7 @@ void SConfig::SaveGameListSettings(IniFile& ini)
|
|||
gamelist->Set("ColumnID", m_showIDColumn);
|
||||
gamelist->Set("ColumnRegion", m_showRegionColumn);
|
||||
gamelist->Set("ColumnSize", m_showSizeColumn);
|
||||
gamelist->Set("ColumnTags", m_showTagsColumn);
|
||||
}
|
||||
|
||||
void SConfig::SaveCoreSettings(IniFile& ini)
|
||||
|
@ -475,6 +476,7 @@ void SConfig::LoadGameListSettings(IniFile& ini)
|
|||
gamelist->Get("ColumnID", &m_showIDColumn, false);
|
||||
gamelist->Get("ColumnRegion", &m_showRegionColumn, true);
|
||||
gamelist->Get("ColumnSize", &m_showSizeColumn, true);
|
||||
gamelist->Get("ColumnTags", &m_showTagsColumn, false);
|
||||
}
|
||||
|
||||
void SConfig::LoadCoreSettings(IniFile& ini)
|
||||
|
|
|
@ -270,6 +270,7 @@ struct SConfig
|
|||
bool m_showIDColumn;
|
||||
bool m_showRegionColumn;
|
||||
bool m_showSizeColumn;
|
||||
bool m_showTagsColumn;
|
||||
|
||||
std::string m_WirelessMac;
|
||||
bool m_PauseMovie;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <QFileInfo>
|
||||
#include <QFrame>
|
||||
#include <QHeaderView>
|
||||
#include <QInputDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QListView>
|
||||
|
@ -132,6 +133,7 @@ void GameList::MakeListView()
|
|||
hor_header->setSectionResizeMode(GameListModel::COL_COUNTRY, QHeaderView::Fixed);
|
||||
hor_header->setSectionResizeMode(GameListModel::COL_SIZE, QHeaderView::Fixed);
|
||||
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
|
||||
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_FILE_NAME,
|
||||
!SConfig::GetInstance().m_showFileNameColumn);
|
||||
m_list->setColumnHidden(GameListModel::COL_TAGS, !SConfig::GetInstance().m_showTagsColumn);
|
||||
}
|
||||
|
||||
void GameList::MakeEmptyView()
|
||||
|
@ -336,6 +339,35 @@ void GameList::ShowContextMenu(const QPoint&)
|
|||
menu->addAction(tr("Open &containing folder"), this, &GameList::OpenContainingFolder);
|
||||
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);
|
||||
|
||||
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("Game ID"), GameListModel::COL_ID},
|
||||
{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);
|
||||
}
|
||||
|
@ -859,6 +892,26 @@ void GameList::OnHeaderViewChanged()
|
|||
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)
|
||||
{
|
||||
m_model->SetSearchTerm(term);
|
||||
|
|
|
@ -60,6 +60,8 @@ private:
|
|||
void ExportWiiSave();
|
||||
void CompressISO(bool decompress);
|
||||
void ChangeDisc();
|
||||
void NewTag();
|
||||
void DeleteTag();
|
||||
void UpdateColumnVisibility();
|
||||
|
||||
void ZoomIn();
|
||||
|
|
|
@ -42,6 +42,11 @@ GameListModel::GameListModel(QObject* parent) : QAbstractTableModel(parent)
|
|||
emit layoutAboutToBeChanged();
|
||||
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
|
||||
|
@ -117,6 +122,14 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
|
|||
if (role == Qt::InitialSortOrderRole)
|
||||
return static_cast<quint64>(game.GetFileSize());
|
||||
break;
|
||||
case COL_TAGS:
|
||||
if (role == Qt::DisplayRole || role == Qt::InitialSortOrderRole)
|
||||
{
|
||||
auto tags = GetGameTags(game.GetFilePath());
|
||||
tags.sort();
|
||||
|
||||
return tags.join(QStringLiteral(", "));
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
|
@ -143,6 +156,8 @@ QVariant GameListModel::headerData(int section, Qt::Orientation orientation, int
|
|||
return tr("File Name");
|
||||
case COL_SIZE:
|
||||
return tr("Size");
|
||||
case COL_TAGS:
|
||||
return tr("Tags");
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -293,3 +308,57 @@ float GameListModel::GetScale() const
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
#include <string>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
|
||||
#include "Core/TitleDatabase.h"
|
||||
|
||||
|
@ -52,6 +55,7 @@ public:
|
|||
COL_COUNTRY,
|
||||
COL_SIZE,
|
||||
COL_FILE_NAME,
|
||||
COL_TAGS,
|
||||
NUM_COLS
|
||||
};
|
||||
|
||||
|
@ -62,10 +66,22 @@ public:
|
|||
void SetScale(float scale);
|
||||
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:
|
||||
// Index in m_games, or -1 if it isn't found
|
||||
int FindGame(const std::string& path) const;
|
||||
|
||||
QStringList m_tag_list;
|
||||
QMap<QString, QVariant> m_game_tags;
|
||||
|
||||
GameTracker m_tracker;
|
||||
QList<std::shared_ptr<const UICommon::GameFile>> m_games;
|
||||
Core::TitleDatabase m_title_database;
|
||||
|
|
|
@ -570,7 +570,8 @@ void MenuBar::AddListColumnsMenu(QMenu* view_menu)
|
|||
{tr("File Name"), &SConfig::GetInstance().m_showFileNameColumn},
|
||||
{tr("Game ID"), &SConfig::GetInstance().m_showIDColumn},
|
||||
{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);
|
||||
QMenu* cols_menu = view_menu->addMenu(tr("List Columns"));
|
||||
|
|
Loading…
Reference in New Issue