Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #7455 from spycrab/qt_tags
Qt/GameList: Implement tag system
  • Loading branch information
delroth committed Oct 13, 2018
2 parents 58361d8 + 6e873c6 commit 2bdee9b
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Source/Core/Core/ConfigManager.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/ConfigManager.h
Expand Up @@ -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;
Expand Down
55 changes: 54 additions & 1 deletion Source/Core/DolphinQt/GameList/GameList.cpp
Expand Up @@ -14,6 +14,7 @@
#include <QFileInfo>
#include <QFrame>
#include <QHeaderView>
#include <QInputDialog>
#include <QKeyEvent>
#include <QLabel>
#include <QListView>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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] {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/GameList/GameList.h
Expand Up @@ -60,6 +60,8 @@ class GameList final : public QStackedWidget
void ExportWiiSave();
void CompressISO(bool decompress);
void ChangeDisc();
void NewTag();
void DeleteTag();
void UpdateColumnVisibility();

void ZoomIn();
Expand Down
69 changes: 69 additions & 0 deletions Source/Core/DolphinQt/GameList/GameListModel.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -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();
}
Expand Down Expand Up @@ -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);
}
16 changes: 16 additions & 0 deletions Source/Core/DolphinQt/GameList/GameListModel.h
Expand Up @@ -8,7 +8,10 @@
#include <string>

#include <QAbstractTableModel>
#include <QMap>
#include <QString>
#include <QStringList>
#include <QVariant>

#include "Core/TitleDatabase.h"

Expand Down Expand Up @@ -52,6 +55,7 @@ class GameListModel final : public QAbstractTableModel
COL_COUNTRY,
COL_SIZE,
COL_FILE_NAME,
COL_TAGS,
NUM_COLS
};

Expand All @@ -62,10 +66,22 @@ class GameListModel final : public QAbstractTableModel
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;
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/DolphinQt/MenuBar.cpp
Expand Up @@ -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"));
Expand Down

0 comments on commit 2bdee9b

Please sign in to comment.