2022-03-17 23:18:33 +01:00
# include "stdafx.h"
2020-12-05 13:08:24 +01:00
# include "trophy_manager_dialog.h"
2018-05-17 22:36:31 +02:00
# include "custom_table_widget_item.h"
2023-04-23 10:36:42 +02:00
# include "game_list_delegate.h"
2018-05-17 22:36:31 +02:00
# include "qt_utils.h"
2018-07-29 08:55:15 +02:00
# include "game_list.h"
2020-02-22 20:42:49 +01:00
# include "gui_settings.h"
2023-04-24 23:37:24 +02:00
# include "progress_dialog.h"
2023-05-15 23:22:13 +02:00
# include "persistent_settings.h"
2017-10-26 18:09:44 +02:00
2020-03-07 10:29:23 +01:00
# include "util/logs.hpp"
2017-10-26 18:09:44 +02:00
# include "Utilities/StrUtil.h"
2020-12-22 09:42:57 +01:00
# include "Utilities/File.h"
2020-02-22 20:42:49 +01:00
# include "Emu/VFS.h"
2017-10-26 18:09:44 +02:00
# include "Emu/System.h"
2021-04-21 22:12:21 +02:00
# include "Emu/system_utils.hpp"
2017-10-26 18:09:44 +02:00
# include "Emu/Cell/Modules/sceNpTrophy.h"
2023-05-15 23:22:13 +02:00
# include "Emu/Cell/Modules/cellRtc.h"
2017-10-26 18:09:44 +02:00
2022-12-06 00:38:30 +01:00
# include <QApplication>
# include <QClipboard>
2019-07-27 14:37:54 +02:00
# include <QtConcurrent>
2019-07-27 16:30:34 +02:00
# include <QFutureWatcher>
2017-10-26 18:09:44 +02:00
# include <QHeaderView>
# include <QVBoxLayout>
# include <QCheckBox>
# include <QGroupBox>
# include <QPixmap>
# include <QDir>
# include <QMenu>
# include <QDesktopServices>
2018-05-17 22:36:31 +02:00
# include <QScrollBar>
2018-06-15 16:46:57 +02:00
# include <QWheelEvent>
2019-08-10 13:24:14 +02:00
# include <QGuiApplication>
# include <QScreen>
2017-10-26 18:09:44 +02:00
2020-02-01 08:43:43 +01:00
LOG_CHANNEL ( gui_log , " GUI " ) ;
2020-02-01 05:15:50 +01:00
2017-10-26 18:09:44 +02:00
namespace
{
constexpr auto qstr = QString : : fromStdString ;
inline std : : string sstr ( const QString & _in ) { return _in . toUtf8 ( ) . toStdString ( ) ; }
}
2023-04-24 21:03:47 +02:00
enum GameUserRole
{
GameIndex = Qt : : UserRole ,
GamePixmapLoaded ,
GamePixmap
} ;
2017-11-22 12:11:59 +01:00
trophy_manager_dialog : : trophy_manager_dialog ( std : : shared_ptr < gui_settings > gui_settings )
2021-04-07 23:05:18 +02:00
: QWidget ( )
, m_gui_settings ( std : : move ( gui_settings ) )
2017-10-26 18:09:44 +02:00
{
// Nonspecific widget settings
setWindowTitle ( tr ( " Trophy Manager " ) ) ;
2018-02-28 01:21:58 +01:00
setObjectName ( " trophy_manager " ) ;
2018-07-08 11:48:38 +02:00
setAttribute ( Qt : : WA_DeleteOnClose ) ;
2020-07-14 01:31:38 +02:00
setAttribute ( Qt : : WA_StyledBackground ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 19:30:13 +02:00
m_game_icon_size_index = m_gui_settings - > GetValue ( gui : : tr_game_iconSize ) . toInt ( ) ;
2017-11-22 12:11:59 +01:00
m_icon_height = m_gui_settings - > GetValue ( gui : : tr_icon_height ) . toInt ( ) ;
m_show_locked_trophies = m_gui_settings - > GetValue ( gui : : tr_show_locked ) . toBool ( ) ;
m_show_unlocked_trophies = m_gui_settings - > GetValue ( gui : : tr_show_unlocked ) . toBool ( ) ;
m_show_hidden_trophies = m_gui_settings - > GetValue ( gui : : tr_show_hidden ) . toBool ( ) ;
m_show_bronze_trophies = m_gui_settings - > GetValue ( gui : : tr_show_bronze ) . toBool ( ) ;
m_show_silver_trophies = m_gui_settings - > GetValue ( gui : : tr_show_silver ) . toBool ( ) ;
m_show_gold_trophies = m_gui_settings - > GetValue ( gui : : tr_show_gold ) . toBool ( ) ;
m_show_platinum_trophies = m_gui_settings - > GetValue ( gui : : tr_show_platinum ) . toBool ( ) ;
2021-10-30 19:48:52 +02:00
// Make sure the directory is mounted
vfs : : mount ( " /dev_hdd0 " , rpcs3 : : utils : : get_hdd0_dir ( ) ) ;
2018-03-17 07:17:27 +01:00
// Get the currently selected user's trophy path.
2018-06-14 00:11:51 +02:00
m_trophy_dir = " /dev_hdd0/home/ " + Emu . GetUsr ( ) + " /trophy/ " ;
2018-03-17 07:17:27 +01:00
2018-05-17 22:36:31 +02:00
// Game chooser combo box
m_game_combo = new QComboBox ( ) ;
2018-05-19 23:37:32 +02:00
m_game_combo - > setSizeAdjustPolicy ( QComboBox : : AdjustToMinimumContentsLengthWithIcon ) ;
2018-05-17 22:36:31 +02:00
// Game progression label
m_game_progress = new QLabel ( tr ( " Progress: %1% (%2/%3) " ) . arg ( 0 ) . arg ( 0 ) . arg ( 0 ) ) ;
// Games Table
2018-07-29 08:55:15 +02:00
m_game_table = new game_list ( ) ;
2018-07-07 20:23:08 +02:00
m_game_table - > setObjectName ( " trophy_manager_game_table " ) ;
2018-05-17 22:36:31 +02:00
m_game_table - > setShowGrid ( false ) ;
m_game_table - > setVerticalScrollMode ( QAbstractItemView : : ScrollPerPixel ) ;
m_game_table - > setHorizontalScrollMode ( QAbstractItemView : : ScrollPerPixel ) ;
2018-06-15 16:46:57 +02:00
m_game_table - > verticalScrollBar ( ) - > installEventFilter ( this ) ;
2018-05-17 22:36:31 +02:00
m_game_table - > verticalScrollBar ( ) - > setSingleStep ( 20 ) ;
m_game_table - > horizontalScrollBar ( ) - > setSingleStep ( 20 ) ;
2023-04-23 10:36:42 +02:00
m_game_table - > setItemDelegate ( new game_list_delegate ( m_game_table ) ) ;
2018-05-17 22:36:31 +02:00
m_game_table - > setSelectionBehavior ( QAbstractItemView : : SelectRows ) ;
2018-05-20 02:14:06 +02:00
m_game_table - > setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
2018-05-17 22:36:31 +02:00
m_game_table - > setEditTriggers ( QAbstractItemView : : NoEditTriggers ) ;
2023-05-18 11:29:23 +02:00
m_game_table - > setColumnCount ( static_cast < int > ( gui : : trophy_game_list_columns : : count ) ) ;
2018-05-17 22:36:31 +02:00
m_game_table - > horizontalHeader ( ) - > setDefaultAlignment ( Qt : : AlignLeft ) ;
m_game_table - > horizontalHeader ( ) - > setStretchLastSection ( true ) ;
m_game_table - > verticalHeader ( ) - > setSectionResizeMode ( QHeaderView : : Fixed ) ;
2022-12-06 00:39:10 +01:00
m_game_table - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
2018-05-17 22:36:31 +02:00
m_game_table - > verticalHeader ( ) - > setVisible ( false ) ;
m_game_table - > setAlternatingRowColors ( true ) ;
2018-06-15 16:46:57 +02:00
m_game_table - > installEventFilter ( this ) ;
2018-05-17 22:36:31 +02:00
2023-05-18 11:29:23 +02:00
auto add_game_column = [ this ] ( gui : : trophy_game_list_columns col , const QString & header_text , const QString & action_text )
{
m_game_table - > setHorizontalHeaderItem ( static_cast < int > ( col ) , new QTableWidgetItem ( header_text ) ) ;
m_game_column_acts . append ( new QAction ( action_text , this ) ) ;
} ;
add_game_column ( gui : : trophy_game_list_columns : : icon , tr ( " Icon " ) , tr ( " Show Icons " ) ) ;
add_game_column ( gui : : trophy_game_list_columns : : name , tr ( " Game " ) , tr ( " Show Games " ) ) ;
add_game_column ( gui : : trophy_game_list_columns : : progress , tr ( " Progress " ) , tr ( " Show Progress " ) ) ;
2018-05-17 22:36:31 +02:00
// Trophy Table
2018-07-29 08:55:15 +02:00
m_trophy_table = new game_list ( ) ;
2018-07-07 20:23:08 +02:00
m_trophy_table - > setObjectName ( " trophy_manager_trophy_table " ) ;
2018-05-17 22:36:31 +02:00
m_trophy_table - > setShowGrid ( false ) ;
m_trophy_table - > setVerticalScrollMode ( QAbstractItemView : : ScrollPerPixel ) ;
m_trophy_table - > setHorizontalScrollMode ( QAbstractItemView : : ScrollPerPixel ) ;
2018-06-15 16:46:57 +02:00
m_trophy_table - > verticalScrollBar ( ) - > installEventFilter ( this ) ;
2018-05-17 22:36:31 +02:00
m_trophy_table - > verticalScrollBar ( ) - > setSingleStep ( 20 ) ;
m_trophy_table - > horizontalScrollBar ( ) - > setSingleStep ( 20 ) ;
2023-04-23 10:36:42 +02:00
m_trophy_table - > setItemDelegate ( new game_list_delegate ( m_trophy_table ) ) ;
2018-05-17 22:36:31 +02:00
m_trophy_table - > setSelectionBehavior ( QAbstractItemView : : SelectRows ) ;
m_trophy_table - > setEditTriggers ( QAbstractItemView : : NoEditTriggers ) ;
2023-05-18 11:29:23 +02:00
m_trophy_table - > setColumnCount ( static_cast < int > ( gui : : trophy_list_columns : : count ) ) ;
2018-05-17 22:36:31 +02:00
m_trophy_table - > horizontalHeader ( ) - > setDefaultAlignment ( Qt : : AlignLeft ) ;
m_trophy_table - > horizontalHeader ( ) - > setStretchLastSection ( true ) ;
2023-05-18 11:29:23 +02:00
m_trophy_table - > horizontalHeader ( ) - > setSectionResizeMode ( static_cast < int > ( gui : : trophy_list_columns : : icon ) , QHeaderView : : Fixed ) ;
2018-05-17 22:36:31 +02:00
m_trophy_table - > verticalHeader ( ) - > setVisible ( false ) ;
m_trophy_table - > verticalHeader ( ) - > setSectionResizeMode ( QHeaderView : : Fixed ) ;
m_trophy_table - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
2018-05-17 19:30:13 +02:00
m_trophy_table - > setAlternatingRowColors ( true ) ;
2018-06-15 16:46:57 +02:00
m_trophy_table - > installEventFilter ( this ) ;
2018-05-17 22:36:31 +02:00
2023-05-18 11:29:23 +02:00
auto add_trophy_column = [ this ] ( gui : : trophy_list_columns col , const QString & header_text , const QString & action_text )
{
m_trophy_table - > setHorizontalHeaderItem ( static_cast < int > ( col ) , new QTableWidgetItem ( header_text ) ) ;
m_trophy_column_acts . append ( new QAction ( action_text , this ) ) ;
} ;
add_trophy_column ( gui : : trophy_list_columns : : icon , tr ( " Icon " ) , tr ( " Show Icons " ) ) ;
add_trophy_column ( gui : : trophy_list_columns : : name , tr ( " Name " ) , tr ( " Show Names " ) ) ;
add_trophy_column ( gui : : trophy_list_columns : : description , tr ( " Description " ) , tr ( " Show Descriptions " ) ) ;
add_trophy_column ( gui : : trophy_list_columns : : type , tr ( " Type " ) , tr ( " Show Types " ) ) ;
add_trophy_column ( gui : : trophy_list_columns : : is_unlocked , tr ( " Status " ) , tr ( " Show Status " ) ) ;
add_trophy_column ( gui : : trophy_list_columns : : id , tr ( " ID " ) , tr ( " Show IDs " ) ) ;
add_trophy_column ( gui : : trophy_list_columns : : platinum_link , tr ( " Platinum Relevant " ) , tr ( " Show Platinum Relevant " ) ) ;
2023-05-15 23:22:13 +02:00
add_trophy_column ( gui : : trophy_list_columns : : time_unlocked , tr ( " Time Unlocked " ) , tr ( " Show Time Unlocked " ) ) ;
2023-05-18 11:29:23 +02:00
2018-05-17 22:36:31 +02:00
m_splitter = new QSplitter ( ) ;
m_splitter - > addWidget ( m_game_table ) ;
m_splitter - > addWidget ( m_trophy_table ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 19:30:13 +02:00
m_game_icon_size = gui_settings : : SizeFromSlider ( m_game_icon_size_index ) ;
2017-10-26 18:09:44 +02:00
// Checkboxes to control dialog
2020-09-03 09:55:48 +02:00
QCheckBox * check_lock_trophy = new QCheckBox ( tr ( " Show Not Earned Trophies " ) ) ;
2017-10-26 18:09:44 +02:00
check_lock_trophy - > setCheckable ( true ) ;
2017-11-22 12:11:59 +01:00
check_lock_trophy - > setChecked ( m_show_locked_trophies ) ;
2017-10-26 18:09:44 +02:00
2020-09-03 09:55:48 +02:00
QCheckBox * check_unlock_trophy = new QCheckBox ( tr ( " Show Earned Trophies " ) ) ;
2017-10-26 18:09:44 +02:00
check_unlock_trophy - > setCheckable ( true ) ;
2017-11-22 12:11:59 +01:00
check_unlock_trophy - > setChecked ( m_show_unlocked_trophies ) ;
2017-10-26 18:09:44 +02:00
QCheckBox * check_hidden_trophy = new QCheckBox ( tr ( " Show Hidden Trophies " ) ) ;
2017-11-22 12:11:59 +01:00
check_hidden_trophy - > setCheckable ( true ) ;
check_hidden_trophy - > setChecked ( m_show_hidden_trophies ) ;
QCheckBox * check_bronze_trophy = new QCheckBox ( tr ( " Show Bronze Trophies " ) ) ;
check_bronze_trophy - > setCheckable ( true ) ;
check_bronze_trophy - > setChecked ( m_show_bronze_trophies ) ;
QCheckBox * check_silver_trophy = new QCheckBox ( tr ( " Show Silver Trophies " ) ) ;
check_silver_trophy - > setCheckable ( true ) ;
check_silver_trophy - > setChecked ( m_show_silver_trophies ) ;
QCheckBox * check_gold_trophy = new QCheckBox ( tr ( " Show Gold Trophies " ) ) ;
check_gold_trophy - > setCheckable ( true ) ;
check_gold_trophy - > setChecked ( m_show_gold_trophies ) ;
QCheckBox * check_platinum_trophy = new QCheckBox ( tr ( " Show Platinum Trophies " ) ) ;
check_platinum_trophy - > setCheckable ( true ) ;
check_platinum_trophy - > setChecked ( m_show_platinum_trophies ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 19:30:13 +02:00
QLabel * trophy_slider_label = new QLabel ( ) ;
trophy_slider_label - > setText ( tr ( " Trophy Icon Size: %0x%1 " ) . arg ( m_icon_height ) . arg ( m_icon_height ) ) ;
QLabel * game_slider_label = new QLabel ( ) ;
game_slider_label - > setText ( tr ( " Game Icon Size: %0x%1 " ) . arg ( m_game_icon_size . width ( ) ) . arg ( m_game_icon_size . height ( ) ) ) ;
2017-10-26 18:09:44 +02:00
2017-11-22 12:11:59 +01:00
m_icon_slider = new QSlider ( Qt : : Horizontal ) ;
m_icon_slider - > setRange ( 25 , 225 ) ;
m_icon_slider - > setValue ( m_icon_height ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 19:30:13 +02:00
m_game_icon_slider = new QSlider ( Qt : : Horizontal ) ;
m_game_icon_slider - > setRange ( 0 , gui : : gl_max_slider_pos ) ;
m_game_icon_slider - > setValue ( m_game_icon_size_index ) ;
2017-10-26 18:09:44 +02:00
// LAYOUTS
2018-05-17 22:36:31 +02:00
QGroupBox * choose_game = new QGroupBox ( tr ( " Choose Game " ) ) ;
QVBoxLayout * choose_layout = new QVBoxLayout ( ) ;
choose_layout - > addWidget ( m_game_combo ) ;
choose_game - > setLayout ( choose_layout ) ;
QGroupBox * trophy_info = new QGroupBox ( tr ( " Trophy Info " ) ) ;
QVBoxLayout * info_layout = new QVBoxLayout ( ) ;
info_layout - > addWidget ( m_game_progress ) ;
trophy_info - > setLayout ( info_layout ) ;
2017-11-22 12:11:59 +01:00
QGroupBox * show_settings = new QGroupBox ( tr ( " Trophy View Options " ) ) ;
2017-10-26 18:09:44 +02:00
QVBoxLayout * settings_layout = new QVBoxLayout ( ) ;
settings_layout - > addWidget ( check_lock_trophy ) ;
settings_layout - > addWidget ( check_unlock_trophy ) ;
settings_layout - > addWidget ( check_hidden_trophy ) ;
2017-11-22 12:11:59 +01:00
settings_layout - > addWidget ( check_bronze_trophy ) ;
settings_layout - > addWidget ( check_silver_trophy ) ;
settings_layout - > addWidget ( check_gold_trophy ) ;
settings_layout - > addWidget ( check_platinum_trophy ) ;
show_settings - > setLayout ( settings_layout ) ;
2018-05-17 19:30:13 +02:00
QGroupBox * icon_settings = new QGroupBox ( tr ( " Icon Options " ) ) ;
2017-11-22 12:11:59 +01:00
QVBoxLayout * slider_layout = new QVBoxLayout ( ) ;
2018-05-17 19:30:13 +02:00
slider_layout - > addWidget ( trophy_slider_label ) ;
2017-11-22 12:11:59 +01:00
slider_layout - > addWidget ( m_icon_slider ) ;
2018-05-17 19:30:13 +02:00
slider_layout - > addWidget ( game_slider_label ) ;
slider_layout - > addWidget ( m_game_icon_slider ) ;
2017-11-22 12:11:59 +01:00
icon_settings - > setLayout ( slider_layout ) ;
QVBoxLayout * options_layout = new QVBoxLayout ( ) ;
2018-05-17 22:36:31 +02:00
options_layout - > addWidget ( choose_game ) ;
options_layout - > addWidget ( trophy_info ) ;
2017-11-22 12:11:59 +01:00
options_layout - > addWidget ( show_settings ) ;
options_layout - > addWidget ( icon_settings ) ;
options_layout - > addStretch ( ) ;
2017-10-26 18:09:44 +02:00
QHBoxLayout * all_layout = new QHBoxLayout ( this ) ;
2017-11-22 12:11:59 +01:00
all_layout - > addLayout ( options_layout ) ;
2018-05-17 22:36:31 +02:00
all_layout - > addWidget ( m_splitter ) ;
2017-11-22 12:11:59 +01:00
all_layout - > setStretch ( 1 , 1 ) ;
2017-10-26 18:09:44 +02:00
setLayout ( all_layout ) ;
// Make connects
2021-06-06 10:43:39 +02:00
connect ( m_icon_slider , & QSlider : : valueChanged , this , [ this , trophy_slider_label ] ( int val )
2017-11-22 12:11:59 +01:00
{
2018-05-17 22:36:31 +02:00
m_icon_height = val ;
2019-12-18 14:35:46 +01:00
if ( trophy_slider_label )
{
trophy_slider_label - > setText ( tr ( " Trophy Icon Size: %0x%1 " ) . arg ( val ) . arg ( val ) ) ;
}
2018-05-18 09:58:04 +02:00
ResizeTrophyIcons ( ) ;
2017-11-22 12:11:59 +01:00
if ( m_save_icon_height )
{
m_save_icon_height = false ;
m_gui_settings - > SetValue ( gui : : tr_icon_height , val ) ;
}
} ) ;
2021-06-06 10:43:39 +02:00
connect ( m_icon_slider , & QSlider : : sliderReleased , this , [ this ] ( )
2017-11-22 12:11:59 +01:00
{
m_gui_settings - > SetValue ( gui : : tr_icon_height , m_icon_slider - > value ( ) ) ;
} ) ;
2021-06-06 10:43:39 +02:00
connect ( m_icon_slider , & QSlider : : actionTriggered , this , [ this ] ( int action )
2017-11-22 12:11:59 +01:00
{
if ( action ! = QAbstractSlider : : SliderNoAction & & action ! = QAbstractSlider : : SliderMove )
{ // we only want to save on mouseclicks or slider release (the other connect handles this)
m_save_icon_height = true ; // actionTriggered happens before the value was changed
}
2017-10-26 18:09:44 +02:00
} ) ;
2017-11-22 12:11:59 +01:00
2021-06-06 10:43:39 +02:00
connect ( m_game_icon_slider , & QSlider : : valueChanged , this , [ this , game_slider_label ] ( int val )
2018-05-17 19:30:13 +02:00
{
m_game_icon_size_index = val ;
2019-12-18 14:35:46 +01:00
m_game_icon_size = gui_settings : : SizeFromSlider ( val ) ;
if ( game_slider_label )
{
game_slider_label - > setText ( tr ( " Game Icon Size: %0x%1 " ) . arg ( m_game_icon_size . width ( ) ) . arg ( m_game_icon_size . height ( ) ) ) ;
}
2018-05-18 09:58:04 +02:00
ResizeGameIcons ( ) ;
2018-05-17 19:30:13 +02:00
if ( m_save_game_icon_size )
{
m_save_game_icon_size = false ;
m_gui_settings - > SetValue ( gui : : tr_game_iconSize , val ) ;
}
} ) ;
2021-06-06 10:43:39 +02:00
connect ( m_game_icon_slider , & QSlider : : sliderReleased , this , [ this ] ( )
2018-05-17 19:30:13 +02:00
{
m_gui_settings - > SetValue ( gui : : tr_game_iconSize , m_game_icon_slider - > value ( ) ) ;
} ) ;
2021-06-06 10:43:39 +02:00
connect ( m_game_icon_slider , & QSlider : : actionTriggered , this , [ this ] ( int action )
2018-05-17 19:30:13 +02:00
{
if ( action ! = QAbstractSlider : : SliderNoAction & & action ! = QAbstractSlider : : SliderMove )
{ // we only want to save on mouseclicks or slider release (the other connect handles this)
m_save_game_icon_size = true ; // actionTriggered happens before the value was changed
}
} ) ;
2021-06-06 10:43:39 +02:00
connect ( check_lock_trophy , & QCheckBox : : clicked , this , [ this ] ( bool checked )
2017-11-22 12:11:59 +01:00
{
m_show_locked_trophies = checked ;
2017-10-26 18:09:44 +02:00
ApplyFilter ( ) ;
2017-11-22 12:11:59 +01:00
m_gui_settings - > SetValue ( gui : : tr_show_locked , checked ) ;
2017-10-26 18:09:44 +02:00
} ) ;
2021-06-06 10:43:39 +02:00
connect ( check_unlock_trophy , & QCheckBox : : clicked , this , [ this ] ( bool checked )
2017-11-22 12:11:59 +01:00
{
m_show_unlocked_trophies = checked ;
2017-10-26 18:09:44 +02:00
ApplyFilter ( ) ;
2017-11-22 12:11:59 +01:00
m_gui_settings - > SetValue ( gui : : tr_show_unlocked , checked ) ;
2017-10-26 18:09:44 +02:00
} ) ;
2021-06-06 10:43:39 +02:00
connect ( check_hidden_trophy , & QCheckBox : : clicked , this , [ this ] ( bool checked )
2017-11-22 12:11:59 +01:00
{
m_show_hidden_trophies = checked ;
2017-10-26 18:09:44 +02:00
ApplyFilter ( ) ;
2017-11-22 12:11:59 +01:00
m_gui_settings - > SetValue ( gui : : tr_show_hidden , checked ) ;
2017-10-26 18:09:44 +02:00
} ) ;
2021-06-06 10:43:39 +02:00
connect ( check_bronze_trophy , & QCheckBox : : clicked , this , [ this ] ( bool checked )
2017-11-22 12:11:59 +01:00
{
m_show_bronze_trophies = checked ;
ApplyFilter ( ) ;
m_gui_settings - > SetValue ( gui : : tr_show_bronze , checked ) ;
} ) ;
2021-06-06 10:43:39 +02:00
connect ( check_silver_trophy , & QCheckBox : : clicked , this , [ this ] ( bool checked )
2017-11-22 12:11:59 +01:00
{
m_show_silver_trophies = checked ;
ApplyFilter ( ) ;
m_gui_settings - > SetValue ( gui : : tr_show_silver , checked ) ;
} ) ;
2021-06-06 10:43:39 +02:00
connect ( check_gold_trophy , & QCheckBox : : clicked , this , [ this ] ( bool checked )
2017-11-22 12:11:59 +01:00
{
m_show_gold_trophies = checked ;
ApplyFilter ( ) ;
m_gui_settings - > SetValue ( gui : : tr_show_gold , checked ) ;
} ) ;
2021-06-06 10:43:39 +02:00
connect ( check_platinum_trophy , & QCheckBox : : clicked , this , [ this ] ( bool checked )
2017-11-22 12:11:59 +01:00
{
m_show_platinum_trophies = checked ;
ApplyFilter ( ) ;
m_gui_settings - > SetValue ( gui : : tr_show_platinum , checked ) ;
} ) ;
2022-12-06 00:39:10 +01:00
connect ( m_trophy_table , & QTableWidget : : customContextMenuRequested , this , & trophy_manager_dialog : : ShowTrophyTableContextMenu ) ;
2018-05-17 22:36:31 +02:00
2021-06-06 10:43:39 +02:00
connect ( m_game_combo , & QComboBox : : currentTextChanged , this , [ this ]
2018-05-17 22:36:31 +02:00
{
2018-07-07 20:23:08 +02:00
PopulateTrophyTable ( ) ;
2018-05-17 22:36:31 +02:00
ApplyFilter ( ) ;
} ) ;
2017-11-22 12:11:59 +01:00
2022-12-06 00:39:10 +01:00
connect ( m_game_table , & QTableWidget : : customContextMenuRequested , this , & trophy_manager_dialog : : ShowGameTableContextMenu ) ;
2021-06-06 10:43:39 +02:00
connect ( m_game_table , & QTableWidget : : itemSelectionChanged , this , [ this ]
2018-05-17 22:36:31 +02:00
{
2018-07-29 08:55:15 +02:00
if ( m_game_table - > selectedItems ( ) . isEmpty ( ) )
{
return ;
}
2023-05-18 11:29:23 +02:00
QTableWidgetItem * item = m_game_table - > item ( m_game_table - > selectedItems ( ) . first ( ) - > row ( ) , static_cast < int > ( gui : : trophy_game_list_columns : : name ) ) ;
2019-08-10 13:50:27 +02:00
if ( ! item )
{
return ;
}
m_game_combo - > setCurrentText ( item - > text ( ) ) ;
2018-05-17 22:36:31 +02:00
} ) ;
2018-05-17 19:30:13 +02:00
2023-04-23 10:36:42 +02:00
connect ( this , & trophy_manager_dialog : : TrophyIconReady , this , [ this ] ( int index , const QPixmap & pixmap )
2021-10-30 20:44:25 +02:00
{
2023-05-18 11:29:23 +02:00
if ( QTableWidgetItem * icon_item = m_trophy_table - > item ( index , static_cast < int > ( gui : : trophy_list_columns : : icon ) ) )
2021-10-30 20:44:25 +02:00
{
2023-04-23 10:36:42 +02:00
icon_item - > setData ( Qt : : DecorationRole , pixmap ) ;
2021-10-30 20:44:25 +02:00
}
} ) ;
2023-04-23 10:36:42 +02:00
connect ( this , & trophy_manager_dialog : : GameIconReady , this , [ this ] ( int index , const QPixmap & pixmap )
2021-10-30 20:44:25 +02:00
{
2023-05-18 11:29:23 +02:00
if ( QTableWidgetItem * icon_item = m_game_table - > item ( index , static_cast < int > ( gui : : trophy_game_list_columns : : icon ) ) )
2021-10-30 20:44:25 +02:00
{
2023-04-23 10:36:42 +02:00
icon_item - > setData ( Qt : : DecorationRole , pixmap ) ;
2021-10-30 20:44:25 +02:00
}
} ) ;
2023-05-18 11:29:23 +02:00
m_trophy_table - > create_header_actions ( m_trophy_column_acts ,
[ this ] ( int col ) { return m_gui_settings - > GetTrophylistColVisibility ( static_cast < gui : : trophy_list_columns > ( col ) ) ; } ,
[ this ] ( int col , bool visible ) { m_gui_settings - > SetTrophylistColVisibility ( static_cast < gui : : trophy_list_columns > ( col ) , visible ) ; } ) ;
m_game_table - > create_header_actions ( m_game_column_acts ,
[ this ] ( int col ) { return m_gui_settings - > GetTrophyGamelistColVisibility ( static_cast < gui : : trophy_game_list_columns > ( col ) ) ; } ,
[ this ] ( int col , bool visible ) { m_gui_settings - > SetTrophyGamelistColVisibility ( static_cast < gui : : trophy_game_list_columns > ( col ) , visible ) ; } ) ;
2019-08-10 14:06:53 +02:00
RepaintUI ( true ) ;
2018-10-31 19:38:48 +01:00
2019-07-27 16:30:34 +02:00
StartTrophyLoadThreads ( ) ;
2018-10-31 19:38:48 +01:00
}
trophy_manager_dialog : : ~ trophy_manager_dialog ( )
{
2023-04-23 10:36:42 +02:00
WaitAndAbortGameRepaintThreads ( ) ;
WaitAndAbortTrophyRepaintThreads ( ) ;
2017-10-26 18:09:44 +02:00
}
2017-10-30 04:32:51 +01:00
bool trophy_manager_dialog : : LoadTrophyFolderToDB ( const std : : string & trop_name )
2017-10-26 18:09:44 +02:00
{
2021-10-30 19:48:52 +02:00
const std : : string trophy_path = m_trophy_dir + trop_name ;
const std : : string vfs_path = vfs : : get ( trophy_path + " / " ) ;
if ( vfs_path . empty ( ) )
{
gui_log . error ( " Failed to load trophy database for %s. Path empty! " , trop_name ) ;
return false ;
}
2017-10-26 18:09:44 +02:00
// Populate GameTrophiesData
std : : unique_ptr < GameTrophiesData > game_trophy_data = std : : make_unique < GameTrophiesData > ( ) ;
2021-10-30 19:48:52 +02:00
game_trophy_data - > path = vfs_path ;
2017-10-26 18:09:44 +02:00
game_trophy_data - > trop_usr . reset ( new TROPUSRLoader ( ) ) ;
2021-10-30 19:48:52 +02:00
const std : : string tropusr_path = trophy_path + " /TROPUSR.DAT " ;
const std : : string tropconf_path = trophy_path + " /TROPCONF.SFM " ;
2021-06-06 10:43:39 +02:00
const bool success = game_trophy_data - > trop_usr - > Load ( tropusr_path , tropconf_path ) . success ;
2017-10-26 18:09:44 +02:00
2021-06-06 10:43:39 +02:00
fs : : file config ( vfs : : get ( tropconf_path ) ) ;
2017-10-26 18:09:44 +02:00
if ( ! success | | ! config )
{
2020-02-01 05:15:50 +01:00
gui_log . error ( " Failed to load trophy database for %s " , trop_name ) ;
2017-10-26 18:09:44 +02:00
return false ;
}
2019-12-18 14:35:46 +01:00
const u32 trophy_count = game_trophy_data - > trop_usr - > GetTrophiesCount ( ) ;
if ( trophy_count = = 0 )
2017-10-31 02:57:15 +01:00
{
2021-06-06 10:00:43 +02:00
gui_log . error ( " Warning game %s in trophy folder %s usr file reports zero trophies. Cannot load in trophy manager. " , game_trophy_data - > game_name , game_trophy_data - > path ) ;
2017-10-31 02:57:15 +01:00
return false ;
}
2019-12-18 14:35:46 +01:00
for ( u32 trophy_id = 0 ; trophy_id < trophy_count ; + + trophy_id )
2017-10-26 18:09:44 +02:00
{
2021-06-06 10:00:43 +02:00
// A trophy icon has 3 digits from 000 to 999, for example TROP001.PNG
2021-06-06 10:43:39 +02:00
game_trophy_data - > trophy_image_paths [ trophy_id ] = qstr ( fmt : : format ( " %sTROP%03d.PNG " , game_trophy_data - > path , trophy_id ) ) ;
2017-10-26 18:09:44 +02:00
}
2017-10-30 04:32:51 +01:00
// Get game name
2022-03-17 23:18:33 +01:00
pugi : : xml_parse_result res = game_trophy_data - > trop_config . Read ( config . to_string ( ) ) ;
if ( ! res )
2017-10-30 04:32:51 +01:00
{
2022-03-17 23:18:33 +01:00
gui_log . error ( " Failed to read trophy xml: %s " , tropconf_path ) ;
return false ;
2017-10-30 04:32:51 +01:00
}
2022-03-17 23:18:33 +01:00
std : : shared_ptr < rXmlNode > trophy_base = game_trophy_data - > trop_config . GetRoot ( ) ;
2023-05-28 13:36:45 +02:00
if ( ! trophy_base )
{
gui_log . error ( " Failed to read trophy xml (root is null): %s " , tropconf_path ) ;
return false ;
}
2022-03-17 23:18:33 +01:00
2017-10-30 04:32:51 +01:00
for ( std : : shared_ptr < rXmlNode > n = trophy_base - > GetChildren ( ) ; n ; n = n - > GetNext ( ) )
{
if ( n - > GetName ( ) = = " title-name " )
{
game_trophy_data - > game_name = n - > GetNodeContent ( ) ;
break ;
}
}
2021-06-06 10:43:39 +02:00
{
std : : scoped_lock lock ( m_trophies_db_mtx ) ;
m_trophies_db . push_back ( std : : move ( game_trophy_data ) ) ;
}
2017-10-30 04:32:51 +01:00
2017-10-26 18:09:44 +02:00
config . release ( ) ;
return true ;
}
2019-08-10 14:06:53 +02:00
void trophy_manager_dialog : : RepaintUI ( bool restore_layout )
2018-07-07 20:23:08 +02:00
{
if ( m_gui_settings - > GetValue ( gui : : m_enableUIColors ) . toBool ( ) )
{
2019-08-10 14:06:53 +02:00
m_game_icon_color = m_gui_settings - > GetValue ( gui : : tr_icon_color ) . value < QColor > ( ) ;
2018-07-07 20:23:08 +02:00
}
else
{
2019-08-10 14:06:53 +02:00
m_game_icon_color = gui : : utils : : get_label_color ( " trophy_manager_icon_background_color " ) ;
2018-07-07 20:23:08 +02:00
}
PopulateGameTable ( ) ;
2019-08-10 14:06:53 +02:00
if ( restore_layout & & ! restoreGeometry ( m_gui_settings - > GetValue ( gui : : tr_geometry ) . toByteArray ( ) ) )
2018-07-07 20:23:08 +02:00
{
2019-08-10 13:24:14 +02:00
resize ( QGuiApplication : : primaryScreen ( ) - > availableSize ( ) * 0.7 ) ;
2018-07-07 20:23:08 +02:00
}
2019-08-10 14:06:53 +02:00
if ( restore_layout & & ! m_splitter - > restoreState ( m_gui_settings - > GetValue ( gui : : tr_splitterState ) . toByteArray ( ) ) )
2018-07-07 20:23:08 +02:00
{
const int width_left = m_splitter - > width ( ) * 0.4 ;
const int width_right = m_splitter - > width ( ) - width_left ;
m_splitter - > setSizes ( { width_left , width_right } ) ;
}
PopulateTrophyTable ( ) ;
2021-04-07 23:05:18 +02:00
const QByteArray game_table_state = m_gui_settings - > GetValue ( gui : : tr_games_state ) . toByteArray ( ) ;
2019-08-10 14:06:53 +02:00
if ( restore_layout & & ! m_game_table - > horizontalHeader ( ) - > restoreState ( game_table_state ) & & m_game_table - > rowCount ( ) )
2018-07-07 20:23:08 +02:00
{
// If no settings exist, resize to contents. (disabled)
//m_game_table->verticalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents);
//m_game_table->horizontalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents);
}
2021-04-07 23:05:18 +02:00
const QByteArray trophy_table_state = m_gui_settings - > GetValue ( gui : : tr_trophy_state ) . toByteArray ( ) ;
2019-08-10 14:06:53 +02:00
if ( restore_layout & & ! m_trophy_table - > horizontalHeader ( ) - > restoreState ( trophy_table_state ) & & m_trophy_table - > rowCount ( ) )
2018-07-07 20:23:08 +02:00
{
// If no settings exist, resize to contents. (disabled)
//m_trophy_table->verticalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents);
//m_trophy_table->horizontalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents);
}
ApplyFilter ( ) ;
// Show dialog and then paint gui in order to adjust headers correctly
show ( ) ;
ReadjustGameTable ( ) ;
ReadjustTrophyTable ( ) ;
}
2018-07-08 11:48:38 +02:00
void trophy_manager_dialog : : HandleRepaintUiRequest ( )
{
2019-08-10 14:06:53 +02:00
const QSize window_size = size ( ) ;
const QByteArray splitter_state = m_splitter - > saveState ( ) ;
const QByteArray game_table_state = m_game_table - > horizontalHeader ( ) - > saveState ( ) ;
const QByteArray trophy_table_state = m_trophy_table - > horizontalHeader ( ) - > saveState ( ) ;
RepaintUI ( false ) ;
m_splitter - > restoreState ( splitter_state ) ;
m_game_table - > horizontalHeader ( ) - > restoreState ( game_table_state ) ;
m_trophy_table - > horizontalHeader ( ) - > restoreState ( trophy_table_state ) ;
resize ( window_size ) ;
2018-07-08 11:48:38 +02:00
}
2018-05-18 09:58:04 +02:00
void trophy_manager_dialog : : ResizeGameIcons ( )
2018-05-17 19:30:13 +02:00
{
if ( m_game_combo - > count ( ) < = 0 )
return ;
2023-04-23 10:36:42 +02:00
WaitAndAbortGameRepaintThreads ( ) ;
2021-10-30 20:44:25 +02:00
QPixmap placeholder ( m_game_icon_size ) ;
placeholder . fill ( Qt : : transparent ) ;
2023-04-24 21:03:47 +02:00
qRegisterMetaType < QVector < int > > ( " QVector<int> " ) ;
2019-07-27 14:37:54 +02:00
QList < int > indices ;
2018-05-17 19:30:13 +02:00
for ( int i = 0 ; i < m_game_table - > rowCount ( ) ; + + i )
2021-10-30 20:44:25 +02:00
{
2019-07-27 14:37:54 +02:00
indices . append ( i ) ;
2023-05-18 11:29:23 +02:00
if ( QTableWidgetItem * icon_item = m_game_table - > item ( i , static_cast < int > ( gui : : trophy_game_list_columns : : icon ) ) )
2021-10-30 20:44:25 +02:00
{
icon_item - > setData ( Qt : : DecorationRole , placeholder ) ;
}
}
2018-05-17 19:30:13 +02:00
ReadjustGameTable ( ) ;
2021-10-30 20:44:25 +02:00
2023-04-23 10:36:42 +02:00
for ( int i = 0 ; i < m_game_table - > rowCount ( ) ; + + i )
{
2023-05-18 11:29:23 +02:00
if ( movie_item * item = static_cast < movie_item * > ( m_game_table - > item ( i , static_cast < int > ( gui : : trophy_game_list_columns : : icon ) ) ) )
2023-04-23 10:36:42 +02:00
{
const qreal dpr = devicePixelRatioF ( ) ;
const int trophy_index = item - > data ( GameUserRole : : GameIndex ) . toInt ( ) ;
const std : : string icon_path = m_trophies_db [ trophy_index ] - > path + " ICON0.PNG " ;
2023-04-24 21:03:47 +02:00
item - > set_icon_load_func ( [ this , icon_path , trophy_index , cancel = item - > icon_loading_aborted ( ) , dpr ] ( int index )
2023-04-23 10:36:42 +02:00
{
if ( cancel & & cancel - > load ( ) )
{
return ;
}
QPixmap icon ;
2023-05-18 11:29:23 +02:00
if ( movie_item * item = static_cast < movie_item * > ( m_game_table - > item ( index , static_cast < int > ( gui : : trophy_game_list_columns : : icon ) ) ) )
2023-04-23 10:36:42 +02:00
{
if ( ! item - > data ( GameUserRole : : GamePixmapLoaded ) . toBool ( ) )
{
// Load game icon
const std : : string icon_path = m_trophies_db [ trophy_index ] - > path + " ICON0.PNG " ;
if ( ! icon . load ( qstr ( icon_path ) ) )
{
gui_log . warning ( " Could not load trophy game icon from path %s " , icon_path ) ;
}
item - > setData ( GameUserRole : : GamePixmapLoaded , true ) ;
item - > setData ( GameUserRole : : GamePixmap , icon ) ;
}
else
{
icon = item - > data ( GameUserRole : : GamePixmap ) . value < QPixmap > ( ) ;
}
}
if ( cancel & & cancel - > load ( ) )
{
return ;
}
QPixmap new_icon ( icon . size ( ) * dpr ) ;
new_icon . setDevicePixelRatio ( dpr ) ;
new_icon . fill ( m_game_icon_color ) ;
if ( ! icon . isNull ( ) )
{
QPainter painter ( & new_icon ) ;
painter . setRenderHint ( QPainter : : SmoothPixmapTransform ) ;
painter . drawPixmap ( QPoint ( 0 , 0 ) , icon ) ;
painter . end ( ) ;
}
new_icon = new_icon . scaled ( m_game_icon_size * dpr , Qt : : KeepAspectRatio , Qt : : TransformationMode : : SmoothTransformation ) ;
if ( ! cancel | | ! cancel - > load ( ) )
{
Q_EMIT GameIconReady ( index , new_icon ) ;
}
} ) ;
}
}
2018-05-17 19:30:13 +02:00
}
2018-05-18 09:58:04 +02:00
void trophy_manager_dialog : : ResizeTrophyIcons ( )
2017-10-26 18:09:44 +02:00
{
2018-05-17 22:36:31 +02:00
if ( m_game_combo - > count ( ) < = 0 )
return ;
2017-10-26 18:09:44 +02:00
2023-04-23 10:36:42 +02:00
WaitAndAbortTrophyRepaintThreads ( ) ;
2021-10-30 20:44:25 +02:00
2019-07-27 10:57:07 +02:00
const int db_pos = m_game_combo - > currentData ( ) . toInt ( ) ;
2020-01-16 18:29:37 +01:00
const qreal dpr = devicePixelRatioF ( ) ;
2019-07-27 10:57:07 +02:00
const int new_height = m_icon_height * dpr ;
2018-05-17 22:36:31 +02:00
2021-10-30 20:44:25 +02:00
QPixmap placeholder ( m_icon_height , m_icon_height ) ;
placeholder . fill ( Qt : : transparent ) ;
2018-05-17 22:36:31 +02:00
for ( int i = 0 ; i < m_trophy_table - > rowCount ( ) ; + + i )
2017-10-26 18:09:44 +02:00
{
2023-05-18 11:29:23 +02:00
if ( QTableWidgetItem * icon_item = m_trophy_table - > item ( i , static_cast < int > ( gui : : trophy_list_columns : : icon ) ) )
2021-10-30 20:44:25 +02:00
{
icon_item - > setData ( Qt : : DecorationRole , placeholder ) ;
}
2021-06-06 10:43:39 +02:00
}
2021-06-06 10:26:44 +02:00
2021-10-30 20:44:25 +02:00
ReadjustTrophyTable ( ) ;
2023-04-23 10:36:42 +02:00
for ( int i = 0 ; i < m_trophy_table - > rowCount ( ) ; + + i )
2021-06-06 10:43:39 +02:00
{
2023-05-18 11:29:23 +02:00
if ( QTableWidgetItem * id_item = m_trophy_table - > item ( i , static_cast < int > ( gui : : trophy_list_columns : : id ) ) )
2021-06-06 10:26:44 +02:00
{
2023-05-18 11:29:23 +02:00
if ( movie_item * item = static_cast < movie_item * > ( m_trophy_table - > item ( i , static_cast < int > ( gui : : trophy_list_columns : : icon ) ) ) )
2021-06-06 10:26:44 +02:00
{
2023-04-24 21:03:47 +02:00
item - > set_icon_load_func ( [ this , data = : : at32 ( m_trophies_db , db_pos ) . get ( ) , trophy_id = id_item - > text ( ) . toInt ( ) , cancel = item - > icon_loading_aborted ( ) , dpr , new_height ] ( int index )
2023-04-23 10:36:42 +02:00
{
if ( cancel & & cancel - > load ( ) )
{
return ;
}
QPixmap icon ;
if ( data )
{
bool found_icon { } ;
QString path ;
{
std : : scoped_lock lock ( m_trophies_db_mtx ) ;
found_icon = data - > trophy_images . contains ( trophy_id ) ;
if ( found_icon )
{
icon = data - > trophy_images [ trophy_id ] ;
}
else
{
path = data - > trophy_image_paths [ trophy_id ] ;
}
}
if ( ! found_icon )
{
if ( icon . load ( path ) )
{
std : : scoped_lock lock ( m_trophies_db_mtx ) ;
data - > trophy_images [ trophy_id ] = icon ;
}
else
{
gui_log . error ( " Failed to load trophy icon for trophy %d (icon='%s') " , trophy_id , sstr ( path ) ) ;
}
}
}
if ( cancel & & cancel - > load ( ) )
{
return ;
}
QPixmap new_icon ( icon . size ( ) * dpr ) ;
new_icon . setDevicePixelRatio ( dpr ) ;
new_icon . fill ( m_game_icon_color ) ;
if ( ! icon . isNull ( ) )
{
QPainter painter ( & new_icon ) ;
painter . setRenderHint ( QPainter : : SmoothPixmapTransform ) ;
painter . drawPixmap ( QPoint ( 0 , 0 ) , icon ) ;
painter . end ( ) ;
}
new_icon = new_icon . scaledToHeight ( new_height , Qt : : SmoothTransformation ) ;
if ( ! cancel | | ! cancel - > load ( ) )
{
Q_EMIT TrophyIconReady ( index , new_icon ) ;
}
} ) ;
2021-06-06 10:26:44 +02:00
}
}
2023-04-23 10:36:42 +02:00
}
2017-10-26 18:09:44 +02:00
}
2018-05-17 22:36:31 +02:00
void trophy_manager_dialog : : ApplyFilter ( )
2017-10-26 18:09:44 +02:00
{
2019-12-18 14:35:46 +01:00
if ( ! m_game_combo | | m_game_combo - > count ( ) < = 0 )
return ;
const int db_pos = m_game_combo - > currentData ( ) . toInt ( ) ;
2021-10-30 20:44:25 +02:00
if ( db_pos < 0 | | static_cast < usz > ( db_pos ) > = m_trophies_db . size ( ) | | ! m_trophies_db [ db_pos ] )
2018-05-17 22:36:31 +02:00
return ;
2017-10-26 18:09:44 +02:00
2021-10-30 20:44:25 +02:00
const TROPUSRLoader * trop_usr = m_trophies_db [ db_pos ] - > trop_usr . get ( ) ;
2019-12-18 14:35:46 +01:00
if ( ! trop_usr )
return ;
2017-10-26 18:09:44 +02:00
2018-05-17 22:36:31 +02:00
for ( int i = 0 ; i < m_trophy_table - > rowCount ( ) ; + + i )
2017-10-26 18:09:44 +02:00
{
2023-05-18 11:29:23 +02:00
QTableWidgetItem * item = m_trophy_table - > item ( i , static_cast < int > ( gui : : trophy_list_columns : : id ) ) ;
QTableWidgetItem * type_item = m_trophy_table - > item ( i , static_cast < int > ( gui : : trophy_list_columns : : type ) ) ;
QTableWidgetItem * icon_item = m_trophy_table - > item ( i , static_cast < int > ( gui : : trophy_list_columns : : icon ) ) ;
2019-08-10 13:50:27 +02:00
if ( ! item | | ! type_item | | ! icon_item )
{
continue ;
}
2020-04-06 23:23:08 +02:00
const int trophy_id = item - > text ( ) . toInt ( ) ;
const int trophy_type = type_item - > data ( Qt : : UserRole ) . toInt ( ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 22:36:31 +02:00
// I could use boolean logic and reduce this to something much shorter and also much more confusing...
2019-12-18 14:35:46 +01:00
const bool hidden = icon_item - > data ( Qt : : UserRole ) . toBool ( ) ;
const bool trophy_unlocked = trop_usr - > GetTrophyUnlockState ( trophy_id ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 22:36:31 +02:00
bool hide = false ;
2019-12-18 14:35:46 +01:00
// Special override to show *just* hidden trophies.
if ( ! m_show_unlocked_trophies & & ! m_show_locked_trophies & & m_show_hidden_trophies )
{
hide = ! hidden ;
}
2021-04-07 23:05:18 +02:00
else if ( ( trophy_unlocked & & ! m_show_unlocked_trophies )
| | ( ! trophy_unlocked & & ! m_show_locked_trophies )
| | ( hidden & & ! trophy_unlocked & & ! m_show_hidden_trophies )
| | ( trophy_type = = SCE_NP_TROPHY_GRADE_BRONZE & & ! m_show_bronze_trophies )
| | ( trophy_type = = SCE_NP_TROPHY_GRADE_SILVER & & ! m_show_silver_trophies )
| | ( trophy_type = = SCE_NP_TROPHY_GRADE_GOLD & & ! m_show_gold_trophies )
| | ( trophy_type = = SCE_NP_TROPHY_GRADE_PLATINUM & & ! m_show_platinum_trophies ) )
2018-05-17 22:36:31 +02:00
{
hide = true ;
}
2017-10-26 18:09:44 +02:00
2018-05-17 22:36:31 +02:00
m_trophy_table - > setRowHidden ( i , hide ) ;
2017-10-26 18:09:44 +02:00
}
2018-05-20 04:53:23 +02:00
ReadjustTrophyTable ( ) ;
2017-10-26 18:09:44 +02:00
}
2022-12-06 00:39:10 +01:00
void trophy_manager_dialog : : ShowTrophyTableContextMenu ( const QPoint & pos )
2017-10-26 18:09:44 +02:00
{
2022-12-06 00:38:30 +01:00
const int row = m_trophy_table - > currentRow ( ) ;
2023-05-18 11:29:23 +02:00
if ( ! m_trophy_table - > item ( row , static_cast < int > ( gui : : trophy_list_columns : : icon ) ) )
2017-10-26 18:09:44 +02:00
{
return ;
}
2019-11-05 17:53:08 +01:00
QMenu * menu = new QMenu ( ) ;
2022-12-06 00:38:30 +01:00
QAction * show_trophy_dir = new QAction ( tr ( " &Open Trophy Directory " ) , menu ) ;
2017-10-26 18:09:44 +02:00
2019-11-05 17:53:08 +01:00
const int db_ind = m_game_combo - > currentData ( ) . toInt ( ) ;
2017-10-26 18:09:44 +02:00
2021-06-06 10:43:39 +02:00
connect ( show_trophy_dir , & QAction : : triggered , this , [ this , db_ind ] ( )
2017-11-22 12:11:59 +01:00
{
2021-04-07 23:05:18 +02:00
const QString path = qstr ( m_trophies_db [ db_ind ] - > path ) ;
2022-12-10 18:29:44 +01:00
gui : : utils : : open_dir ( path ) ;
2017-10-26 18:09:44 +02:00
} ) ;
2018-09-11 18:02:19 +02:00
2017-10-26 18:09:44 +02:00
menu - > addAction ( show_trophy_dir ) ;
2022-12-06 00:38:30 +01:00
2023-05-18 11:29:23 +02:00
const QTableWidgetItem * name_item = m_trophy_table - > item ( row , static_cast < int > ( gui : : trophy_list_columns : : name ) ) ;
const QTableWidgetItem * desc_item = m_trophy_table - > item ( row , static_cast < int > ( gui : : trophy_list_columns : : description ) ) ;
2022-12-06 00:38:30 +01:00
const QString name = name_item ? name_item - > text ( ) : " " ;
const QString desc = desc_item ? desc_item - > text ( ) : " " ;
if ( ! name . isEmpty ( ) | | ! desc . isEmpty ( ) )
{
QMenu * copy_menu = new QMenu ( tr ( " &Copy Info " ) , menu ) ;
if ( ! name . isEmpty ( ) & & ! desc . isEmpty ( ) )
{
QAction * copy_both = new QAction ( tr ( " &Copy Name + Description " ) , copy_menu ) ;
connect ( copy_both , & QAction : : triggered , this , [ this , name , desc ] ( )
{
QApplication : : clipboard ( ) - > setText ( name % QStringLiteral ( " \n \n " ) % desc ) ;
} ) ;
copy_menu - > addAction ( copy_both ) ;
}
if ( ! name . isEmpty ( ) )
{
QAction * copy_name = new QAction ( tr ( " &Copy Name " ) , copy_menu ) ;
connect ( copy_name , & QAction : : triggered , this , [ this , name ] ( )
{
QApplication : : clipboard ( ) - > setText ( name ) ;
} ) ;
copy_menu - > addAction ( copy_name ) ;
}
if ( ! desc . isEmpty ( ) )
{
QAction * copy_desc = new QAction ( tr ( " &Copy Description " ) , copy_menu ) ;
connect ( copy_desc , & QAction : : triggered , this , [ this , desc ] ( )
{
QApplication : : clipboard ( ) - > setText ( desc ) ;
} ) ;
copy_menu - > addAction ( copy_desc ) ;
}
menu - > addMenu ( copy_menu ) ;
}
2019-11-05 17:53:08 +01:00
menu - > exec ( m_trophy_table - > viewport ( ) - > mapToGlobal ( pos ) ) ;
2017-10-26 18:09:44 +02:00
}
2022-12-06 00:39:10 +01:00
void trophy_manager_dialog : : ShowGameTableContextMenu ( const QPoint & pos )
{
const int row = m_game_table - > currentRow ( ) ;
2023-05-18 11:29:23 +02:00
if ( ! m_game_table - > item ( row , static_cast < int > ( gui : : trophy_game_list_columns : : icon ) ) )
2022-12-06 00:39:10 +01:00
{
return ;
}
QMenu * menu = new QMenu ( ) ;
QAction * show_trophy_dir = new QAction ( tr ( " &Open Trophy Directory " ) , menu ) ;
const int db_ind = m_game_combo - > currentData ( ) . toInt ( ) ;
connect ( show_trophy_dir , & QAction : : triggered , this , [ this , db_ind ] ( )
{
const QString path = qstr ( m_trophies_db [ db_ind ] - > path ) ;
2022-12-10 18:29:44 +01:00
gui : : utils : : open_dir ( path ) ;
2022-12-06 00:39:10 +01:00
} ) ;
menu - > addAction ( show_trophy_dir ) ;
2023-05-18 11:29:23 +02:00
const QTableWidgetItem * name_item = m_game_table - > item ( row , static_cast < int > ( gui : : trophy_game_list_columns : : name ) ) ;
2022-12-06 00:39:10 +01:00
const QString name = name_item ? name_item - > text ( ) : " " ;
if ( ! name . isEmpty ( ) )
{
QAction * copy_name = new QAction ( tr ( " &Copy Name " ) , menu ) ;
connect ( copy_name , & QAction : : triggered , this , [ this , name ] ( )
{
QApplication : : clipboard ( ) - > setText ( name ) ;
} ) ;
menu - > addAction ( copy_name ) ;
}
menu - > exec ( m_game_table - > viewport ( ) - > mapToGlobal ( pos ) ) ;
}
2019-07-27 16:30:34 +02:00
void trophy_manager_dialog : : StartTrophyLoadThreads ( )
2018-07-07 20:23:08 +02:00
{
2023-04-23 10:36:42 +02:00
WaitAndAbortGameRepaintThreads ( ) ;
WaitAndAbortTrophyRepaintThreads ( ) ;
2021-10-30 20:44:25 +02:00
2019-07-27 16:30:34 +02:00
m_trophies_db . clear ( ) ;
2018-10-31 19:38:48 +01:00
2021-10-30 19:48:52 +02:00
const QString trophy_path = qstr ( vfs : : get ( m_trophy_dir ) ) ;
if ( trophy_path . isEmpty ( ) )
{
gui_log . error ( " Cannot load trophy dir. Path empty! " ) ;
RepaintUI ( true ) ;
return ;
}
const QDir trophy_dir ( trophy_path ) ;
2023-05-28 13:36:45 +02:00
const QStringList folder_list = trophy_dir . entryList ( QDir : : Dirs | QDir : : NoDotAndDotDot ) ;
2018-10-31 19:38:48 +01:00
const int count = folder_list . count ( ) ;
2019-07-27 16:30:34 +02:00
if ( count < = 0 )
{
RepaintUI ( true ) ;
return ;
}
2023-04-24 21:03:47 +02:00
qRegisterMetaType < QVector < int > > ( " QVector<int> " ) ;
2019-07-27 16:30:34 +02:00
QList < int > indices ;
for ( int i = 0 ; i < count ; + + i )
indices . append ( i ) ;
QFutureWatcher < void > futureWatcher ;
2023-04-24 23:37:24 +02:00
progress_dialog progressDialog ( tr ( " Loading trophies " ) , tr ( " Loading trophy data, please wait... " ) , tr ( " Cancel " ) , 0 , 1 , false , this , Qt : : Dialog | Qt : : WindowTitleHint | Qt : : CustomizeWindowHint ) ;
2019-07-27 16:30:34 +02:00
connect ( & futureWatcher , & QFutureWatcher < void > : : progressRangeChanged , & progressDialog , & QProgressDialog : : setRange ) ;
connect ( & futureWatcher , & QFutureWatcher < void > : : progressValueChanged , & progressDialog , & QProgressDialog : : setValue ) ;
2021-04-07 23:05:18 +02:00
connect ( & futureWatcher , & QFutureWatcher < void > : : finished , this , [ this ] ( ) { RepaintUI ( true ) ; } ) ;
connect ( & progressDialog , & QProgressDialog : : canceled , this , [ this , & futureWatcher ] ( )
2018-10-31 19:38:48 +01:00
{
2019-07-27 16:30:34 +02:00
futureWatcher . cancel ( ) ;
2021-04-07 23:05:18 +02:00
close ( ) ; // It's pointless to show an empty window
2019-07-27 16:30:34 +02:00
} ) ;
2023-05-28 13:36:45 +02:00
atomic_t < usz > error_count { } ;
futureWatcher . setFuture ( QtConcurrent : : map ( indices , [ this , & error_count , & folder_list ] ( const int & i )
2019-07-27 16:30:34 +02:00
{
const std : : string dir_name = sstr ( folder_list . value ( i ) ) ;
2020-02-01 05:15:50 +01:00
gui_log . trace ( " Loading trophy dir: %s " , dir_name ) ;
2020-03-09 17:18:39 +01:00
if ( ! LoadTrophyFolderToDB ( dir_name ) )
2018-10-31 19:38:48 +01:00
{
2023-05-28 13:36:45 +02:00
// TODO: add a way of showing the number of corrupted/invalid folders in UI somewhere.
2020-03-09 17:18:39 +01:00
gui_log . error ( " Error occurred while parsing folder %s for trophies. " , dir_name ) ;
2023-05-28 13:36:45 +02:00
error_count + + ;
2018-10-31 19:38:48 +01:00
}
2019-07-27 16:30:34 +02:00
} ) ) ;
2018-07-08 11:48:38 +02:00
2019-07-27 16:30:34 +02:00
progressDialog . exec ( ) ;
2018-10-31 19:38:48 +01:00
2019-07-27 16:30:34 +02:00
futureWatcher . waitForFinished ( ) ;
2023-05-28 13:36:45 +02:00
if ( error_count ! = 0 )
{
gui_log . error ( " Failed to load %d of %d trophy folders! " , error_count . load ( ) , count ) ;
}
2018-07-07 20:23:08 +02:00
}
void trophy_manager_dialog : : PopulateGameTable ( )
{
2023-04-23 10:36:42 +02:00
WaitAndAbortGameRepaintThreads ( ) ;
2021-10-30 20:44:25 +02:00
2018-07-07 20:23:08 +02:00
m_game_table - > setSortingEnabled ( false ) ; // Disable sorting before using setItem calls
m_game_table - > clearContents ( ) ;
2019-06-28 19:43:36 +02:00
m_game_table - > setRowCount ( static_cast < int > ( m_trophies_db . size ( ) ) ) ;
2018-07-07 20:23:08 +02:00
m_game_combo - > clear ( ) ;
2023-05-28 13:44:46 +02:00
m_game_combo - > blockSignals ( true ) ;
2018-07-07 20:23:08 +02:00
2023-04-24 21:03:47 +02:00
qRegisterMetaType < QVector < int > > ( " QVector<int> " ) ;
2019-07-27 14:37:54 +02:00
QList < int > indices ;
2020-12-18 08:39:54 +01:00
for ( usz i = 0 ; i < m_trophies_db . size ( ) ; + + i )
2019-08-11 14:36:40 +02:00
indices . append ( static_cast < int > ( i ) ) ;
2019-07-27 14:37:54 +02:00
2021-10-30 20:44:25 +02:00
QPixmap placeholder ( m_game_icon_size ) ;
placeholder . fill ( Qt : : transparent ) ;
2019-08-11 14:36:40 +02:00
for ( int i = 0 ; i < indices . count ( ) ; + + i )
{
const int all_trophies = m_trophies_db [ i ] - > trop_usr - > GetTrophiesCount ( ) ;
const int unlocked_trophies = m_trophies_db [ i ] - > trop_usr - > GetUnlockedTrophiesCount ( ) ;
const int percentage = 100 * unlocked_trophies / all_trophies ;
2020-04-06 17:54:33 +02:00
const QString progress = tr ( " %0% (%1/%2) " ) . arg ( percentage ) . arg ( unlocked_trophies ) . arg ( all_trophies ) ;
2019-08-11 14:36:40 +02:00
const QString name = qstr ( m_trophies_db [ i ] - > game_name ) . simplified ( ) ;
2018-07-07 20:23:08 +02:00
custom_table_widget_item * icon_item = new custom_table_widget_item ;
2021-10-30 20:44:25 +02:00
icon_item - > setData ( Qt : : DecorationRole , placeholder ) ;
icon_item - > setData ( GameUserRole : : GameIndex , i ) ;
icon_item - > setData ( GameUserRole : : GamePixmapLoaded , false ) ;
icon_item - > setData ( GameUserRole : : GamePixmap , QPixmap ( ) ) ;
2018-07-07 20:23:08 +02:00
2023-05-18 11:29:23 +02:00
m_game_table - > setItem ( i , static_cast < int > ( gui : : trophy_game_list_columns : : icon ) , icon_item ) ;
m_game_table - > setItem ( i , static_cast < int > ( gui : : trophy_game_list_columns : : name ) , new custom_table_widget_item ( name ) ) ;
m_game_table - > setItem ( i , static_cast < int > ( gui : : trophy_game_list_columns : : progress ) , new custom_table_widget_item ( progress , Qt : : UserRole , percentage ) ) ;
2018-07-07 20:23:08 +02:00
2019-08-11 14:36:40 +02:00
m_game_combo - > addItem ( name , i ) ;
}
2021-06-06 10:43:39 +02:00
m_game_combo - > model ( ) - > sort ( 0 , Qt : : AscendingOrder ) ;
2023-05-28 13:44:46 +02:00
m_game_combo - > blockSignals ( false ) ;
m_game_combo - > setCurrentIndex ( 0 ) ;
2021-06-06 10:43:39 +02:00
2018-07-07 20:23:08 +02:00
m_game_table - > setSortingEnabled ( true ) ; // Enable sorting only after using setItem calls
2021-10-30 20:44:25 +02:00
ResizeGameIcons ( ) ;
2018-07-07 20:23:08 +02:00
gui : : utils : : resize_combo_box_view ( m_game_combo ) ;
}
void trophy_manager_dialog : : PopulateTrophyTable ( )
2017-10-26 18:09:44 +02:00
{
2018-05-17 22:36:31 +02:00
if ( m_game_combo - > count ( ) < = 0 )
return ;
auto & data = m_trophies_db [ m_game_combo - > currentData ( ) . toInt ( ) ] ;
2020-02-01 05:15:50 +01:00
gui_log . trace ( " Populating Trophy Manager UI with %s %s " , data - > game_name , data - > path ) ;
2018-05-17 22:36:31 +02:00
const int all_trophies = data - > trop_usr - > GetTrophiesCount ( ) ;
const int unlocked_trophies = data - > trop_usr - > GetUnlockedTrophiesCount ( ) ;
const int percentage = 100 * unlocked_trophies / all_trophies ;
2020-04-06 17:54:33 +02:00
m_game_progress - > setText ( tr ( " Progress: %1% (%2/%3) " ) . arg ( percentage ) . arg ( unlocked_trophies ) . arg ( all_trophies ) ) ;
2018-05-17 22:36:31 +02:00
2021-04-18 09:37:32 +02:00
m_trophy_table - > clear_list ( ) ;
2018-05-17 22:36:31 +02:00
m_trophy_table - > setRowCount ( all_trophies ) ;
m_trophy_table - > setSortingEnabled ( false ) ; // Disable sorting before using setItem calls
2021-10-30 20:44:25 +02:00
QPixmap placeholder ( m_icon_height , m_icon_height ) ;
placeholder . fill ( Qt : : transparent ) ;
2023-05-15 23:22:13 +02:00
const QLocale locale { } ;
2023-05-28 13:36:45 +02:00
std : : shared_ptr < rXmlNode > trophy_base = data - > trop_config . GetRoot ( ) ;
if ( ! trophy_base )
{
gui_log . error ( " Populating Trophy Manager UI failed (root is null): %s %s " , data - > game_name , data - > path ) ;
}
2018-05-17 22:36:31 +02:00
int i = 0 ;
2023-05-28 13:36:45 +02:00
for ( std : : shared_ptr < rXmlNode > n = trophy_base ? trophy_base - > GetChildren ( ) : nullptr ; n ; n = n - > GetNext ( ) )
2018-05-17 22:36:31 +02:00
{
// Only show trophies.
if ( n - > GetName ( ) ! = " trophy " )
2017-10-26 18:09:44 +02:00
{
continue ;
}
2018-05-17 22:36:31 +02:00
// Get data (stolen graciously from sceNpTrophy.cpp)
2022-03-17 23:18:33 +01:00
SceNpTrophyDetails details { } ;
2019-12-18 14:35:46 +01:00
// Get trophy id
const s32 trophy_id = atoi ( n - > GetAttribute ( " id " ) . c_str ( ) ) ;
2018-05-17 22:36:31 +02:00
details . trophyId = trophy_id ;
2019-12-18 14:35:46 +01:00
2019-12-18 15:14:11 +01:00
// Get platinum link id (we assume there only exists one platinum trophy per game for now)
const s32 platinum_link_id = atoi ( n - > GetAttribute ( " pid " ) . c_str ( ) ) ;
const QString platinum_relevant = platinum_link_id < 0 ? tr ( " No " ) : tr ( " Yes " ) ;
2019-12-18 14:35:46 +01:00
// Get trophy type
2020-04-06 23:23:08 +02:00
QString trophy_type ;
2017-10-26 18:09:44 +02:00
2018-05-17 22:36:31 +02:00
switch ( n - > GetAttribute ( " ttype " ) [ 0 ] )
{
2020-04-06 23:23:08 +02:00
case ' B ' : details . trophyGrade = SCE_NP_TROPHY_GRADE_BRONZE ; trophy_type = tr ( " Bronze " , " Trophy type " ) ; break ;
case ' S ' : details . trophyGrade = SCE_NP_TROPHY_GRADE_SILVER ; trophy_type = tr ( " Silver " , " Trophy type " ) ; break ;
case ' G ' : details . trophyGrade = SCE_NP_TROPHY_GRADE_GOLD ; trophy_type = tr ( " Gold " , " Trophy type " ) ; break ;
case ' P ' : details . trophyGrade = SCE_NP_TROPHY_GRADE_PLATINUM ; trophy_type = tr ( " Platinum " , " Trophy type " ) ; break ;
2021-04-07 23:05:18 +02:00
default : gui_log . warning ( " Unknown trophy grade %s " , n - > GetAttribute ( " ttype " ) ) ; break ;
2018-05-17 22:36:31 +02:00
}
2017-10-26 18:09:44 +02:00
2019-12-18 14:35:46 +01:00
// Get hidden state
const bool hidden = n - > GetAttribute ( " hidden " ) [ 0 ] = = ' y ' ;
details . hidden = hidden ;
2017-11-22 12:11:59 +01:00
2019-12-18 14:35:46 +01:00
// Get name and detail
2018-05-17 22:36:31 +02:00
for ( std : : shared_ptr < rXmlNode > n2 = n - > GetChildren ( ) ; n2 ; n2 = n2 - > GetNext ( ) )
{
if ( n2 - > GetName ( ) = = " name " )
2017-11-22 12:11:59 +01:00
{
2023-05-28 13:36:45 +02:00
strcpy_trunc ( details . name , n2 - > GetNodeContent ( ) ) ;
2017-10-26 18:09:44 +02:00
}
2018-05-17 22:36:31 +02:00
if ( n2 - > GetName ( ) = = " detail " )
2017-11-22 12:11:59 +01:00
{
2023-05-28 13:36:45 +02:00
strcpy_trunc ( details . description , n2 - > GetNodeContent ( ) ) ;
2017-10-26 18:09:44 +02:00
}
2018-05-17 22:36:31 +02:00
}
2017-10-26 18:09:44 +02:00
2023-05-15 23:22:13 +02:00
// Get timestamp
const u64 tick = data - > trop_usr - > GetTrophyTimestamp ( trophy_id ) ;
const QString datetime = tick ? locale . toString ( TickToDateTime ( tick ) , gui : : persistent : : last_played_date_with_time_of_day_format ) : tr ( " Unknown " ) ;
2020-09-03 09:55:48 +02:00
const QString unlockstate = data - > trop_usr - > GetTrophyUnlockState ( trophy_id ) ? tr ( " Earned " ) : tr ( " Not Earned " ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 22:36:31 +02:00
custom_table_widget_item * icon_item = new custom_table_widget_item ( ) ;
icon_item - > setData ( Qt : : UserRole , hidden , true ) ;
2021-10-30 20:44:25 +02:00
icon_item - > setData ( Qt : : DecorationRole , placeholder ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 22:36:31 +02:00
custom_table_widget_item * type_item = new custom_table_widget_item ( trophy_type ) ;
2021-04-07 23:05:18 +02:00
type_item - > setData ( Qt : : UserRole , static_cast < uint > ( details . trophyGrade ) , true ) ;
2018-05-17 22:36:31 +02:00
2023-05-18 11:29:23 +02:00
m_trophy_table - > setItem ( i , static_cast < int > ( gui : : trophy_list_columns : : icon ) , icon_item ) ;
m_trophy_table - > setItem ( i , static_cast < int > ( gui : : trophy_list_columns : : name ) , new custom_table_widget_item ( qstr ( details . name ) ) ) ;
m_trophy_table - > setItem ( i , static_cast < int > ( gui : : trophy_list_columns : : description ) , new custom_table_widget_item ( qstr ( details . description ) ) ) ;
m_trophy_table - > setItem ( i , static_cast < int > ( gui : : trophy_list_columns : : type ) , type_item ) ;
m_trophy_table - > setItem ( i , static_cast < int > ( gui : : trophy_list_columns : : is_unlocked ) , new custom_table_widget_item ( unlockstate ) ) ;
m_trophy_table - > setItem ( i , static_cast < int > ( gui : : trophy_list_columns : : id ) , new custom_table_widget_item ( QString : : number ( trophy_id ) , Qt : : UserRole , trophy_id ) ) ;
m_trophy_table - > setItem ( i , static_cast < int > ( gui : : trophy_list_columns : : platinum_link ) , new custom_table_widget_item ( platinum_relevant , Qt : : UserRole , platinum_link_id ) ) ;
2023-05-15 23:22:13 +02:00
m_trophy_table - > setItem ( i , static_cast < int > ( gui : : trophy_list_columns : : time_unlocked ) , new custom_table_widget_item ( datetime , Qt : : UserRole , QVariant : : fromValue < qulonglong > ( tick ) ) ) ;
2017-10-26 18:09:44 +02:00
2018-05-17 22:36:31 +02:00
+ + i ;
2017-10-26 18:09:44 +02:00
}
2018-05-17 22:36:31 +02:00
m_trophy_table - > setSortingEnabled ( true ) ; // Re-enable sorting after using setItem calls
2019-08-10 11:18:37 +02:00
ResizeTrophyIcons ( ) ;
2018-05-17 22:36:31 +02:00
}
2021-04-07 23:05:18 +02:00
void trophy_manager_dialog : : ReadjustGameTable ( ) const
2018-05-17 22:36:31 +02:00
{
2018-05-17 19:30:13 +02:00
// Fixate vertical header and row height
m_game_table - > verticalHeader ( ) - > setMinimumSectionSize ( m_game_icon_size . height ( ) ) ;
m_game_table - > verticalHeader ( ) - > setMaximumSectionSize ( m_game_icon_size . height ( ) ) ;
2020-08-21 08:25:53 +02:00
m_game_table - > resizeRowsToContents ( ) ;
2018-05-17 19:30:13 +02:00
2020-08-21 08:25:53 +02:00
// Resize and fixate icon column
2023-05-18 11:29:23 +02:00
m_game_table - > resizeColumnToContents ( static_cast < int > ( gui : : trophy_game_list_columns : : icon ) ) ;
m_game_table - > horizontalHeader ( ) - > setSectionResizeMode ( static_cast < int > ( gui : : trophy_game_list_columns : : icon ) , QHeaderView : : Fixed ) ;
2018-05-17 19:30:13 +02:00
// Shorten the last section to remove horizontal scrollbar if possible
2023-05-18 11:29:23 +02:00
m_game_table - > resizeColumnToContents ( static_cast < int > ( gui : : trophy_game_list_columns : : count ) - 1 ) ;
2018-05-17 19:30:13 +02:00
}
2021-04-07 23:05:18 +02:00
void trophy_manager_dialog : : ReadjustTrophyTable ( ) const
2018-05-17 19:30:13 +02:00
{
// Fixate vertical header and row height
2018-05-17 22:36:31 +02:00
m_trophy_table - > verticalHeader ( ) - > setMinimumSectionSize ( m_icon_height ) ;
m_trophy_table - > verticalHeader ( ) - > setMaximumSectionSize ( m_icon_height ) ;
2020-08-21 08:25:53 +02:00
m_trophy_table - > resizeRowsToContents ( ) ;
2018-05-17 19:30:13 +02:00
2020-08-21 08:25:53 +02:00
// Resize and fixate icon column
2023-05-18 11:29:23 +02:00
m_trophy_table - > resizeColumnToContents ( static_cast < int > ( gui : : trophy_list_columns : : icon ) ) ;
2018-05-17 19:30:13 +02:00
// Shorten the last section to remove horizontal scrollbar if possible
2023-05-18 11:29:23 +02:00
m_trophy_table - > resizeColumnToContents ( static_cast < int > ( gui : : trophy_list_columns : : count ) - 1 ) ;
2017-10-26 18:09:44 +02:00
}
2017-11-22 12:11:59 +01:00
2018-06-15 16:46:57 +02:00
bool trophy_manager_dialog : : eventFilter ( QObject * object , QEvent * event )
{
const bool is_trophy_scroll = object = = m_trophy_table - > verticalScrollBar ( ) ;
const bool is_trophy_table = object = = m_trophy_table ;
const bool is_game_scroll = object = = m_game_table - > verticalScrollBar ( ) ;
const bool is_game_table = object = = m_game_table ;
int zoom_val = 0 ;
switch ( event - > type ( ) )
{
case QEvent : : Wheel :
{
QWheelEvent * wheelEvent = static_cast < QWheelEvent * > ( event ) ;
if ( wheelEvent - > modifiers ( ) & Qt : : ControlModifier & & ( is_trophy_scroll | | is_game_scroll ) )
{
2019-12-18 14:35:46 +01:00
const QPoint numSteps = wheelEvent - > angleDelta ( ) / 8 / 15 ; // http://doc.qt.io/qt-5/qwheelevent.html#pixelDelta
2018-06-15 16:46:57 +02:00
zoom_val = numSteps . y ( ) ;
}
break ;
}
case QEvent : : KeyPress :
{
QKeyEvent * keyEvent = static_cast < QKeyEvent * > ( event ) ;
2021-09-02 20:48:56 +02:00
if ( keyEvent & & keyEvent - > modifiers ( ) = = Qt : : ControlModifier & & ( is_trophy_table | | is_game_table ) )
2018-06-15 16:46:57 +02:00
{
if ( keyEvent - > key ( ) = = Qt : : Key_Plus )
{
zoom_val = 1 ;
}
else if ( keyEvent - > key ( ) = = Qt : : Key_Minus )
{
zoom_val = - 1 ;
}
}
break ;
}
default :
break ;
}
if ( zoom_val ! = 0 )
{
if ( m_icon_slider & & ( is_trophy_table | | is_trophy_scroll ) )
{
m_save_icon_height = true ;
m_icon_slider - > setSliderPosition ( zoom_val + m_icon_slider - > value ( ) ) ;
}
else if ( m_game_icon_slider & & ( is_game_table | | is_game_scroll ) )
{
m_save_game_icon_size = true ;
m_game_icon_slider - > setSliderPosition ( zoom_val + m_game_icon_slider - > value ( ) ) ;
}
return true ;
}
return QWidget : : eventFilter ( object , event ) ;
}
2018-05-18 09:58:04 +02:00
void trophy_manager_dialog : : closeEvent ( QCloseEvent * event )
2017-11-22 12:11:59 +01:00
{
// Save gui settings
m_gui_settings - > SetValue ( gui : : tr_geometry , saveGeometry ( ) ) ;
2018-05-17 22:36:31 +02:00
m_gui_settings - > SetValue ( gui : : tr_splitterState , m_splitter - > saveState ( ) ) ;
m_gui_settings - > SetValue ( gui : : tr_games_state , m_game_table - > horizontalHeader ( ) - > saveState ( ) ) ;
m_gui_settings - > SetValue ( gui : : tr_trophy_state , m_trophy_table - > horizontalHeader ( ) - > saveState ( ) ) ;
2023-06-20 18:22:59 +02:00
m_gui_settings - > sync ( ) ;
2018-05-18 09:58:04 +02:00
QWidget : : closeEvent ( event ) ;
2017-11-22 12:11:59 +01:00
}
2023-04-23 10:36:42 +02:00
void trophy_manager_dialog : : WaitAndAbortGameRepaintThreads ( )
{
for ( int i = 0 ; i < m_game_table - > rowCount ( ) ; i + + )
{
2023-05-18 11:29:23 +02:00
if ( movie_item * item = static_cast < movie_item * > ( m_game_table - > item ( i , static_cast < int > ( gui : : trophy_game_list_columns : : icon ) ) ) )
2023-04-23 10:36:42 +02:00
{
item - > wait_for_icon_loading ( true ) ;
}
}
}
void trophy_manager_dialog : : WaitAndAbortTrophyRepaintThreads ( )
{
for ( int i = 0 ; i < m_trophy_table - > rowCount ( ) ; i + + )
{
2023-05-18 11:29:23 +02:00
if ( movie_item * item = static_cast < movie_item * > ( m_trophy_table - > item ( i , static_cast < int > ( gui : : trophy_list_columns : : icon ) ) ) )
2023-04-23 10:36:42 +02:00
{
item - > wait_for_icon_loading ( true ) ;
}
}
}
2023-05-15 23:22:13 +02:00
QDateTime trophy_manager_dialog : : TickToDateTime ( u64 tick )
{
const CellRtcDateTime rtc_date = tick_to_date_time ( tick ) ;
const QDateTime datetime (
QDate ( rtc_date . year , rtc_date . month , rtc_date . day ) ,
QTime ( rtc_date . hour , rtc_date . minute , rtc_date . second , rtc_date . microsecond / 1000 ) ,
Qt : : TimeSpec : : UTC ) ;
return datetime . toLocalTime ( ) ;
}