diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp index 7824925396..a4514a0449 100644 --- a/Source/Core/DolphinQt/GameList/GameList.cpp +++ b/Source/Core/DolphinQt/GameList/GameList.cpp @@ -208,6 +208,7 @@ void GameList::MakeListView() SetResizeMode(Column::FileFormat, Mode::Fixed); SetResizeMode(Column::BlockSize, Mode::Fixed); SetResizeMode(Column::Compression, Mode::Fixed); + SetResizeMode(Column::TimePlayed, Mode::Interactive); SetResizeMode(Column::Tags, Mode::Interactive); // Cells have 3 pixels of padding, so the width of these needs to be image width + 6. Banners @@ -273,6 +274,7 @@ void GameList::UpdateColumnVisibility() SetVisiblity(Column::FileFormat, Config::Get(Config::MAIN_GAMELIST_COLUMN_FILE_FORMAT)); SetVisiblity(Column::BlockSize, Config::Get(Config::MAIN_GAMELIST_COLUMN_BLOCK_SIZE)); SetVisiblity(Column::Compression, Config::Get(Config::MAIN_GAMELIST_COLUMN_COMPRESSION)); + SetVisiblity(Column::TimePlayed, Config::Get(Config::MAIN_GAMELIST_COLUMN_TIME_PLAYED)); SetVisiblity(Column::Tags, Config::Get(Config::MAIN_GAMELIST_COLUMN_TAGS)); } @@ -1005,6 +1007,7 @@ void GameList::OnColumnVisibilityToggled(const QString& row, bool visible) {tr("File Format"), Column::FileFormat}, {tr("Block Size"), Column::BlockSize}, {tr("Compression"), Column::Compression}, + {tr("Time Played"), Column::TimePlayed}, {tr("Tags"), Column::Tags}, }; diff --git a/Source/Core/DolphinQt/GameList/GameListModel.cpp b/Source/Core/DolphinQt/GameList/GameListModel.cpp index c70a870c23..c8c1d8b165 100644 --- a/Source/Core/DolphinQt/GameList/GameListModel.cpp +++ b/Source/Core/DolphinQt/GameList/GameListModel.cpp @@ -9,6 +9,8 @@ #include #include "Core/Config/MainSettings.h" +#include "Core/Core.h" +#include "Core/TimePlayed.h" #include "DiscIO/Enums.h" @@ -32,6 +34,8 @@ GameListModel::GameListModel(QObject* parent) : QAbstractTableModel(parent) &GameTracker::RefreshAll); connect(&Settings::Instance(), &Settings::TitleDBReloadRequested, [this] { m_title_database = Core::TitleDatabase(); }); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + &GameListModel::OnEmulationStateChanged); for (const QString& dir : Settings::Instance().GetPaths()) m_tracker.AddDirectory(dir); @@ -187,6 +191,25 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const return compression.isEmpty() ? tr("No Compression") : compression; } break; + case Column::TimePlayed: + if (role == Qt::DisplayRole) + { + const std::string game_id = game.GetGameID(); + const std::chrono::milliseconds total_time = m_timer.GetTimePlayed(game_id); + const auto total_minutes = std::chrono::duration_cast(total_time); + const auto total_hours = std::chrono::duration_cast(total_time); + + // i18n: A time displayed as hours and minutes + QString formatted_time = + tr("%1h %2m").arg(total_hours.count()).arg(total_minutes.count() % 60); + return formatted_time; + } + if (role == SORT_ROLE) + { + const std::string game_id = game.GetGameID(); + return static_cast(m_timer.GetTimePlayed(game_id).count()); + } + break; case Column::Tags: if (role == Qt::DisplayRole || role == SORT_ROLE) { @@ -232,6 +255,8 @@ QVariant GameListModel::headerData(int section, Qt::Orientation orientation, int return tr("Block Size"); case Column::Compression: return tr("Compression"); + case Column::TimePlayed: + return tr("Time Played"); case Column::Tags: return tr("Tags"); default: @@ -480,3 +505,11 @@ void GameListModel::PurgeCache() { m_tracker.PurgeCache(); } + +void GameListModel::OnEmulationStateChanged(Core::State state) +{ + if (state == Core::State::Uninitialized) + { + m_timer.Reload(); + } +} diff --git a/Source/Core/DolphinQt/GameList/GameListModel.h b/Source/Core/DolphinQt/GameList/GameListModel.h index b76e0a37c2..baac5d507d 100644 --- a/Source/Core/DolphinQt/GameList/GameListModel.h +++ b/Source/Core/DolphinQt/GameList/GameListModel.h @@ -12,6 +12,8 @@ #include #include +#include "Core/Core.h" +#include "Core/TimePlayed.h" #include "Core/TitleDatabase.h" #include "DolphinQt/GameList/GameTracker.h" @@ -58,6 +60,7 @@ public: FileFormat, BlockSize, Compression, + TimePlayed, Tags, Count, }; @@ -87,12 +90,15 @@ private: // Index in m_games, or -1 if it isn't found int FindGameIndex(const std::string& path) const; + void OnEmulationStateChanged(Core::State state); + QStringList m_tag_list; QMap m_game_tags; GameTracker m_tracker; QList> m_games; Core::TitleDatabase m_title_database; + TimePlayed m_timer; QString m_term; float m_scale = 1.0; }; diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index fef441c062..24c6cc2d04 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -701,6 +701,7 @@ void MenuBar::AddListColumnsMenu(QMenu* view_menu) {tr("File Format"), &Config::MAIN_GAMELIST_COLUMN_FILE_FORMAT}, {tr("Block Size"), &Config::MAIN_GAMELIST_COLUMN_BLOCK_SIZE}, {tr("Compression"), &Config::MAIN_GAMELIST_COLUMN_COMPRESSION}, + {tr("Time Played"), &Config::MAIN_GAMELIST_COLUMN_TIME_PLAYED}, {tr("Tags"), &Config::MAIN_GAMELIST_COLUMN_TAGS}}; QActionGroup* column_group = new QActionGroup(this);