2019-08-10 13:53:52 +02:00
# include " save_manager_dialog.h "
2017-08-14 02:17:45 +02:00
# include "save_data_info_dialog.h"
2022-02-02 15:36:15 +01:00
# include "custom_table_widget_item.h"
2019-08-10 13:53:52 +02:00
# include "qt_utils.h"
2017-08-14 02:17:45 +02:00
# include "Emu/System.h"
# include "Emu/VFS.h"
# include "Loader/PSF.h"
2019-07-27 14:37:54 +02:00
# include <QtConcurrent>
2022-02-02 15:36:15 +01:00
# include <QDateTime>
2017-08-14 02:17:45 +02:00
# include <QIcon>
# include <QHBoxLayout>
# include <QHeaderView>
# include <QMenu>
# include <QMessageBox>
2017-10-24 17:09:38 +02:00
# include <QDesktopWidget>
# include <QApplication>
# include <QUrl>
# include <QDesktopServices>
2022-02-02 15:36:15 +01:00
# include <QPainter>
2019-08-10 13:24:14 +02:00
# include <QScreen>
2017-08-14 02:17:45 +02:00
2020-02-01 05:15:50 +01:00
LOG_CHANNEL ( gui_log ) ;
2017-08-14 02:17:45 +02:00
namespace
{
// Helper converters
2017-09-20 22:25:10 +02:00
constexpr auto qstr = QString : : fromStdString ;
2017-11-27 22:31:15 +01:00
inline std : : string sstr ( const QString & _in ) { return _in . toStdString ( ) ; }
2017-08-14 02:17:45 +02:00
2019-08-10 13:47:25 +02:00
QString FormatTimestamp ( u64 time )
{
2022-02-02 15:36:15 +01:00
QDateTime dateTime ;
dateTime . setTime_t ( time ) ;
return dateTime . toString ( " yyyy-MM-dd HH:mm:ss " ) ;
}
2017-08-14 02:17:45 +02:00
/**
* This certainly isn ' t ideal for this code , as it essentially copies cellSaveData . But , I have no other choice without adding public methods to cellSaveData .
*/
std : : vector < SaveDataEntry > GetSaveEntries ( const std : : string & base_dir )
{
std : : vector < SaveDataEntry > save_entries ;
// get the saves matching the supplied prefix
for ( const auto & entry : fs : : dir ( base_dir ) )
{
2019-05-25 00:01:04 +02:00
if ( ! entry . is_directory | | entry . name = = " . " | | entry . name = = " .. " )
2017-08-14 02:17:45 +02:00
{
continue ;
}
// PSF parameters
const auto & psf = psf : : load_object ( fs : : file ( base_dir + entry . name + " /PARAM.SFO " ) ) ;
if ( psf . empty ( ) )
{
2020-02-01 05:36:53 +01:00
gui_log . error ( " Failed to load savedata: %s " , base_dir + " / " + entry . name ) ;
2017-08-14 02:17:45 +02:00
continue ;
}
SaveDataEntry save_entry2 ;
save_entry2 . dirName = psf . at ( " SAVEDATA_DIRECTORY " ) . as_string ( ) ;
save_entry2 . listParam = psf . at ( " SAVEDATA_LIST_PARAM " ) . as_string ( ) ;
save_entry2 . title = psf . at ( " TITLE " ) . as_string ( ) ;
save_entry2 . subtitle = psf . at ( " SUB_TITLE " ) . as_string ( ) ;
save_entry2 . details = psf . at ( " DETAIL " ) . as_string ( ) ;
save_entry2 . size = 0 ;
2017-11-30 21:55:26 +01:00
for ( const auto & entry2 : fs : : dir ( base_dir + entry . name ) )
2017-08-14 02:17:45 +02:00
{
save_entry2 . size + = entry2 . size ;
}
save_entry2 . atime = entry . atime ;
save_entry2 . mtime = entry . mtime ;
save_entry2 . ctime = entry . ctime ;
if ( fs : : is_file ( base_dir + entry . name + " /ICON0.PNG " ) )
{
fs : : file icon = fs : : file ( base_dir + entry . name + " /ICON0.PNG " ) ;
u32 iconSize = icon . size ( ) ;
std : : vector < uchar > iconData ;
icon . read ( iconData , iconSize ) ;
save_entry2 . iconBuf = iconData ;
}
save_entry2 . isNew = false ;
save_entries . emplace_back ( save_entry2 ) ;
}
return save_entries ;
}
}
2017-11-22 12:11:59 +01:00
save_manager_dialog : : save_manager_dialog ( std : : shared_ptr < gui_settings > gui_settings , std : : string dir , QWidget * parent )
: QDialog ( parent ) , m_save_entries ( ) , m_dir ( dir ) , m_sort_column ( 1 ) , m_sort_ascending ( true ) , m_gui_settings ( gui_settings )
2017-08-14 02:17:45 +02:00
{
setWindowTitle ( tr ( " Save Manager " ) ) ;
setMinimumSize ( QSize ( 400 , 400 ) ) ;
Init ( dir ) ;
}
/*
* Future proofing . Makes it easier in future if I add ability to change directories
*/
void save_manager_dialog : : Init ( std : : string dir )
{
// Table
m_list = new QTableWidget ( this ) ;
//m_list->setItemDelegate(new table_item_delegate(this)); // to get rid of cell selection rectangles include "table_item_delegate.h"
2017-10-24 17:09:38 +02:00
m_list - > setSelectionMode ( QAbstractItemView : : SelectionMode : : ExtendedSelection ) ;
2017-08-14 02:17:45 +02:00
m_list - > setSelectionBehavior ( QAbstractItemView : : SelectRows ) ;
m_list - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
2022-02-02 15:36:15 +01:00
m_list - > setColumnCount ( 5 ) ;
m_list - > setHorizontalHeaderLabels ( QStringList ( ) < < tr ( " Icon " ) < < tr ( " Title & Subtitle " ) < < tr ( " Last Modified " ) < < tr ( " Save ID " ) < < tr ( " Notes " ) ) ;
m_list - > horizontalHeader ( ) - > setSectionResizeMode ( 0 , QHeaderView : : Fixed ) ;
m_list - > horizontalHeader ( ) - > setStretchLastSection ( true ) ;
// Bottom bar
int icon_size = m_gui_settings - > GetValue ( gui : : sd_icon_size ) . toInt ( ) ;
m_icon_size = QSize ( icon_size , icon_size ) ;
QLabel * label_icon_size = new QLabel ( " Icon size: " , this ) ;
QSlider * slider_icon_size = new QSlider ( Qt : : Horizontal , this ) ;
slider_icon_size - > setMinimum ( 60 ) ;
slider_icon_size - > setMaximum ( 225 ) ;
slider_icon_size - > setValue ( m_icon_size . height ( ) ) ;
2017-08-14 02:17:45 +02:00
QPushButton * push_close = new QPushButton ( tr ( " &Close " ) , this ) ;
push_close - > setAutoDefault ( true ) ;
2017-10-24 17:09:38 +02:00
2022-02-02 15:36:15 +01:00
// Details
m_details_icon = new QLabel ( this ) ;
m_details_icon - > setMinimumSize ( 320 , 176 ) ;
m_details_title = new QLabel ( tr ( " Select an item to view details " ) , this ) ;
m_details_title - > setWordWrap ( true ) ;
m_details_subtitle = new QLabel ( this ) ;
m_details_subtitle - > setWordWrap ( true ) ;
m_details_modified = new QLabel ( this ) ;
m_details_modified - > setWordWrap ( true ) ;
m_details_details = new QLabel ( this ) ;
m_details_details - > setWordWrap ( true ) ;
m_details_note = new QLabel ( this ) ;
m_details_note - > setWordWrap ( true ) ;
m_button_delete = new QPushButton ( tr ( " Delete Selection " ) , this ) ;
m_button_delete - > setDisabled ( true ) ;
m_button_folder = new QPushButton ( tr ( " View Folder " ) , this ) ;
m_button_delete - > setDisabled ( true ) ;
// Details layout
QVBoxLayout * vbox_details = new QVBoxLayout ( ) ;
vbox_details - > addWidget ( m_details_icon ) ;
vbox_details - > addWidget ( m_details_title ) ;
vbox_details - > addWidget ( m_details_subtitle ) ;
vbox_details - > addWidget ( m_details_modified ) ;
vbox_details - > addWidget ( m_details_details ) ;
vbox_details - > addWidget ( m_details_note ) ;
vbox_details - > addStretch ( ) ;
vbox_details - > addWidget ( m_button_delete ) ;
vbox_details - > setAlignment ( m_button_delete , Qt : : AlignHCenter ) ;
vbox_details - > addWidget ( m_button_folder ) ;
vbox_details - > setAlignment ( m_button_folder , Qt : : AlignHCenter ) ;
// List + Details
QHBoxLayout * hbox_content = new QHBoxLayout ( ) ;
hbox_content - > addWidget ( m_list ) ;
hbox_content - > addLayout ( vbox_details ) ;
// Items below list
2017-10-24 17:09:38 +02:00
QHBoxLayout * hbox_buttons = new QHBoxLayout ( ) ;
2022-02-02 15:36:15 +01:00
hbox_buttons - > addWidget ( label_icon_size ) ;
hbox_buttons - > addWidget ( slider_icon_size ) ;
2017-08-14 02:17:45 +02:00
hbox_buttons - > addStretch ( ) ;
hbox_buttons - > addWidget ( push_close ) ;
// main layout
QVBoxLayout * vbox_main = new QVBoxLayout ( ) ;
vbox_main - > setAlignment ( Qt : : AlignCenter ) ;
2022-02-02 15:36:15 +01:00
vbox_main - > addLayout ( hbox_content ) ;
2017-08-14 02:17:45 +02:00
vbox_main - > addLayout ( hbox_buttons ) ;
setLayout ( vbox_main ) ;
UpdateList ( ) ;
2022-02-02 15:36:15 +01:00
m_list - > sortByColumn ( 1 , Qt : : AscendingOrder ) ;
2017-08-14 02:17:45 +02:00
2018-03-28 20:08:15 +02:00
if ( restoreGeometry ( m_gui_settings - > GetValue ( gui : : sd_geometry ) . toByteArray ( ) ) )
2019-08-10 13:24:14 +02:00
resize ( size ( ) . expandedTo ( QGuiApplication : : primaryScreen ( ) - > availableSize ( ) * 0.5 ) ) ;
2017-11-22 12:11:59 +01:00
2017-08-14 02:17:45 +02:00
// Connects and events
connect ( push_close , & QAbstractButton : : clicked , this , & save_manager_dialog : : close ) ;
2022-02-02 15:36:15 +01:00
connect ( m_button_delete , & QAbstractButton : : clicked , this , & save_manager_dialog : : OnEntriesRemove ) ;
connect ( m_button_folder , & QAbstractButton : : clicked , [ = ] ( )
{
2019-08-10 13:50:27 +02:00
const int idx = m_list - > currentRow ( ) ;
QTableWidgetItem * item = m_list - > item ( idx , 1 ) ;
if ( ! item )
{
return ;
}
const int idx_real = item - > data ( Qt : : UserRole ) . toInt ( ) ;
const QString path = qstr ( m_dir + m_save_entries [ idx_real ] . dirName + " / " ) ;
2022-02-02 15:36:15 +01:00
QDesktopServices : : openUrl ( QUrl ( " file:/// " + path ) ) ;
} ) ;
connect ( slider_icon_size , & QAbstractSlider : : valueChanged , this , & save_manager_dialog : : SetIconSize ) ;
2017-09-06 19:32:33 +02:00
connect ( m_list - > horizontalHeader ( ) , & QHeaderView : : sectionClicked , this , & save_manager_dialog : : OnSort ) ;
2017-08-14 02:17:45 +02:00
connect ( m_list , & QTableWidget : : customContextMenuRequested , this , & save_manager_dialog : : ShowContextMenu ) ;
2017-09-05 22:40:35 +02:00
connect ( m_list , & QTableWidget : : cellChanged , [ & ] ( int row , int col )
{
2019-08-10 13:50:27 +02:00
QTableWidgetItem * user_item = m_list - > item ( row , 1 ) ;
QTableWidgetItem * text_item = m_list - > item ( row , col ) ;
if ( ! user_item | | ! text_item )
{
return ;
}
const int originalIndex = user_item - > data ( Qt : : UserRole ) . toInt ( ) ;
const SaveDataEntry originalEntry = m_save_entries [ originalIndex ] ;
const QString originalDirName = qstr ( originalEntry . dirName ) ;
2017-11-22 12:11:59 +01:00
QVariantMap currNotes = m_gui_settings - > GetValue ( gui : : m_saveNotes ) . toMap ( ) ;
2019-08-10 13:50:27 +02:00
currNotes [ originalDirName ] = text_item - > text ( ) ;
2017-11-22 12:11:59 +01:00
m_gui_settings - > SetValue ( gui : : m_saveNotes , currNotes ) ;
2017-08-14 02:17:45 +02:00
} ) ;
2022-02-02 15:36:15 +01:00
connect ( m_list , & QTableWidget : : itemSelectionChanged , this , & save_manager_dialog : : UpdateDetails ) ;
2017-08-14 02:17:45 +02:00
}
void save_manager_dialog : : UpdateList ( )
{
if ( m_dir = = " " )
{
2019-06-01 15:52:39 +02:00
m_dir = Emulator : : GetHddDir ( ) + " home/ " + Emu . GetUsr ( ) + " /savedata/ " ;
2017-08-14 02:17:45 +02:00
}
m_save_entries = GetSaveEntries ( m_dir ) ;
m_list - > clearContents ( ) ;
2017-09-20 22:25:10 +02:00
m_list - > setRowCount ( static_cast < int > ( m_save_entries . size ( ) ) ) ;
2017-11-22 12:11:59 +01:00
QVariantMap currNotes = m_gui_settings - > GetValue ( gui : : m_saveNotes ) . toMap ( ) ;
2017-08-14 02:17:45 +02:00
2019-08-10 13:53:52 +02:00
if ( m_gui_settings - > GetValue ( gui : : m_enableUIColors ) . toBool ( ) )
{
m_icon_color = m_gui_settings - > GetValue ( gui : : sd_icon_color ) . value < QColor > ( ) ;
}
else
{
m_icon_color = gui : : utils : : get_label_color ( " save_manager_icon_background_color " ) ;
}
2019-07-27 14:37:54 +02:00
QList < int > indices ;
2019-07-27 16:30:34 +02:00
for ( size_t i = 0 ; i < m_save_entries . size ( ) ; + + i )
indices . append ( static_cast < int > ( i ) ) ;
2019-07-27 14:37:54 +02:00
2019-08-11 14:36:40 +02:00
std : : function < QPixmap ( const int & ) > get_icon = [ this ] ( const int & row )
2017-08-14 02:17:45 +02:00
{
2019-07-27 14:37:54 +02:00
const auto & entry = m_save_entries [ row ] ;
2022-02-02 15:36:15 +01:00
QPixmap icon = QPixmap ( 320 , 176 ) ;
if ( ! icon . loadFromData ( entry . iconBuf . data ( ) , static_cast < uint > ( entry . iconBuf . size ( ) ) ) )
{
2020-02-01 05:15:50 +01:00
gui_log . warning ( " Loading icon for save %s failed " , entry . dirName ) ;
2019-08-10 13:53:52 +02:00
icon = QPixmap ( 320 , 176 ) ;
icon . fill ( m_icon_color ) ;
2022-02-02 15:36:15 +01:00
}
2019-08-11 14:36:40 +02:00
return icon ;
} ;
QList < QPixmap > icons = QtConcurrent : : blockingMapped < QList < QPixmap > > ( indices , get_icon ) ;
for ( int i = 0 ; i < icons . count ( ) ; + + i )
{
const auto & entry = m_save_entries [ i ] ;
2022-02-02 15:36:15 +01:00
QString title = qstr ( entry . title ) + QStringLiteral ( " \n " ) + qstr ( entry . subtitle ) ;
2017-08-14 02:17:45 +02:00
QString dirName = qstr ( entry . dirName ) ;
2022-02-02 15:36:15 +01:00
custom_table_widget_item * iconItem = new custom_table_widget_item ;
2019-08-11 14:36:40 +02:00
iconItem - > setData ( Qt : : UserRole , icons [ i ] ) ;
2022-02-02 15:36:15 +01:00
iconItem - > setFlags ( iconItem - > flags ( ) & ~ Qt : : ItemIsEditable ) ;
2019-08-11 14:36:40 +02:00
m_list - > setItem ( i , 0 , iconItem ) ;
2022-02-02 15:36:15 +01:00
2017-08-14 02:17:45 +02:00
QTableWidgetItem * titleItem = new QTableWidgetItem ( title ) ;
2019-08-11 14:36:40 +02:00
titleItem - > setData ( Qt : : UserRole , i ) ; // For sorting to work properly
2017-08-14 02:17:45 +02:00
titleItem - > setFlags ( titleItem - > flags ( ) & ~ Qt : : ItemIsEditable ) ;
2019-08-11 14:36:40 +02:00
m_list - > setItem ( i , 1 , titleItem ) ;
2017-08-14 02:17:45 +02:00
2022-02-02 15:36:15 +01:00
QTableWidgetItem * timeItem = new QTableWidgetItem ( FormatTimestamp ( entry . mtime ) ) ;
timeItem - > setFlags ( timeItem - > flags ( ) & ~ Qt : : ItemIsEditable ) ;
2019-08-11 14:36:40 +02:00
m_list - > setItem ( i , 2 , timeItem ) ;
2017-08-14 02:17:45 +02:00
QTableWidgetItem * dirNameItem = new QTableWidgetItem ( dirName ) ;
dirNameItem - > setFlags ( dirNameItem - > flags ( ) & ~ Qt : : ItemIsEditable ) ;
2019-08-11 14:36:40 +02:00
m_list - > setItem ( i , 3 , dirNameItem ) ;
2017-08-14 02:17:45 +02:00
QTableWidgetItem * noteItem = new QTableWidgetItem ( ) ;
noteItem - > setFlags ( noteItem - > flags ( ) | Qt : : ItemIsEditable ) ;
if ( currNotes . contains ( dirName ) )
{
noteItem - > setText ( currNotes [ dirName ] . toString ( ) ) ;
}
2019-08-11 14:36:40 +02:00
m_list - > setItem ( i , 4 , noteItem ) ;
}
2017-11-22 12:11:59 +01:00
2019-08-11 14:36:40 +02:00
UpdateIcons ( ) ;
2022-02-02 15:36:15 +01:00
2017-08-14 02:17:45 +02:00
m_list - > horizontalHeader ( ) - > resizeSections ( QHeaderView : : ResizeToContents ) ;
m_list - > verticalHeader ( ) - > resizeSections ( QHeaderView : : ResizeToContents ) ;
QSize tableSize = QSize (
m_list - > verticalHeader ( ) - > width ( ) + m_list - > horizontalHeader ( ) - > length ( ) + m_list - > frameWidth ( ) * 2 ,
m_list - > horizontalHeader ( ) - > height ( ) + m_list - > verticalHeader ( ) - > length ( ) + m_list - > frameWidth ( ) * 2 ) ;
2017-10-28 16:22:18 +02:00
QSize preferredSize = minimumSize ( ) . expandedTo ( sizeHint ( ) - m_list - > sizeHint ( ) + tableSize ) ;
2017-08-14 02:17:45 +02:00
2019-08-10 13:24:14 +02:00
QSize maxSize = QSize ( preferredSize . width ( ) , static_cast < int > ( QGuiApplication : : primaryScreen ( ) - > geometry ( ) . height ( ) * 0.6 ) ) ;
2017-10-28 16:22:18 +02:00
resize ( preferredSize . boundedTo ( maxSize ) ) ;
2017-08-14 02:17:45 +02:00
}
2019-08-10 13:53:52 +02:00
void save_manager_dialog : : HandleRepaintUiRequest ( )
{
const QSize window_size = size ( ) ;
const Qt : : SortOrder sort_order = m_sort_ascending ? Qt : : AscendingOrder : Qt : : DescendingOrder ;
UpdateList ( ) ;
m_list - > sortByColumn ( m_sort_column , sort_order ) ;
resize ( window_size ) ;
}
2019-08-11 14:36:40 +02:00
QPixmap save_manager_dialog : : GetResizedIcon ( int i )
2022-02-02 15:36:15 +01:00
{
2020-01-16 18:29:37 +01:00
const qreal dpr = devicePixelRatioF ( ) ;
2022-02-02 15:36:15 +01:00
const int width = m_icon_size . width ( ) * dpr ;
const int height = m_icon_size . height ( ) * dpr * 176 / 320 ;
2019-07-27 14:37:54 +02:00
QTableWidgetItem * item = m_list - > item ( i , 0 ) ;
if ( ! item )
2022-02-02 15:36:15 +01:00
{
2019-08-11 14:36:40 +02:00
return QPixmap ( ) ;
2019-07-27 14:37:54 +02:00
}
QPixmap data = item - > data ( Qt : : UserRole ) . value < QPixmap > ( ) ;
2022-02-02 15:36:15 +01:00
2019-07-27 14:37:54 +02:00
QPixmap icon = QPixmap ( data . size ( ) * dpr ) ;
icon . setDevicePixelRatio ( dpr ) ;
icon . fill ( m_icon_color ) ;
QPainter painter ( & icon ) ;
painter . drawPixmap ( 0 , 0 , data ) ;
2019-08-11 14:36:40 +02:00
return icon . scaled ( width , height , Qt : : KeepAspectRatio , Qt : : SmoothTransformation ) ;
2019-07-27 14:37:54 +02:00
}
void save_manager_dialog : : UpdateIcons ( )
{
QList < int > indices ;
for ( int i = 0 ; i < m_list - > rowCount ( ) ; + + i )
indices . append ( i ) ;
2019-08-11 14:36:40 +02:00
std : : function < QPixmap ( const int & ) > get_scaled = [ this ] ( const int & i )
2019-07-27 14:37:54 +02:00
{
2019-08-11 14:36:40 +02:00
return GetResizedIcon ( i ) ;
} ;
QList < QPixmap > scaled = QtConcurrent : : blockingMapped < QList < QPixmap > > ( indices , get_scaled ) ;
for ( int i = 0 ; i < m_list - > rowCount ( ) & & i < scaled . count ( ) ; + + i )
{
QTableWidgetItem * icon_item = m_list - > item ( i , 0 ) ;
if ( icon_item )
icon_item - > setData ( Qt : : DecorationRole , scaled [ i ] ) ;
}
2022-02-02 15:36:15 +01:00
m_list - > resizeRowsToContents ( ) ;
m_list - > resizeColumnToContents ( 0 ) ;
}
2017-08-14 02:17:45 +02:00
/**
* Copied method to do sort from save_data_list_dialog
*/
2017-09-06 19:32:33 +02:00
void save_manager_dialog : : OnSort ( int logicalIndex )
2017-08-14 02:17:45 +02:00
{
2017-09-06 19:32:33 +02:00
if ( logicalIndex > = 0 )
2017-08-14 02:17:45 +02:00
{
2017-09-06 19:32:33 +02:00
if ( logicalIndex = = m_sort_column )
2017-08-14 02:17:45 +02:00
{
2017-09-06 19:32:33 +02:00
m_sort_ascending ^ = true ;
2017-08-14 02:17:45 +02:00
}
else
{
2017-09-06 19:32:33 +02:00
m_sort_ascending = true ;
2017-08-14 02:17:45 +02:00
}
2018-06-20 02:15:26 +02:00
m_sort_column = logicalIndex ;
2017-09-06 19:32:33 +02:00
Qt : : SortOrder sort_order = m_sort_ascending ? Qt : : AscendingOrder : Qt : : DescendingOrder ;
m_list - > sortByColumn ( m_sort_column , sort_order ) ;
2017-08-14 02:17:45 +02:00
}
}
2019-05-24 23:54:14 +02:00
// Remove a save file, need to be confirmed.
2017-08-14 02:17:45 +02:00
void save_manager_dialog : : OnEntryRemove ( )
{
int idx = m_list - > currentRow ( ) ;
if ( idx ! = - 1 )
{
2019-08-10 13:50:27 +02:00
QTableWidgetItem * item = m_list - > item ( idx , 1 ) ;
if ( ! item )
{
return ;
}
const int idx_real = item - > data ( Qt : : UserRole ) . toInt ( ) ;
2018-02-10 15:00:06 +01:00
if ( QMessageBox : : question ( this , tr ( " Delete Confirmation " ) , tr ( " Are you sure you want to delete: \n %1? " ) . arg ( qstr ( m_save_entries [ idx_real ] . title ) ) , QMessageBox : : Yes , QMessageBox : : No ) = = QMessageBox : : Yes )
2017-08-14 02:17:45 +02:00
{
2017-08-14 04:35:40 +02:00
fs : : remove_all ( m_dir + m_save_entries [ idx_real ] . dirName + " / " ) ;
m_list - > removeRow ( idx ) ;
2017-08-14 02:17:45 +02:00
}
}
}
2017-10-24 17:09:38 +02:00
void save_manager_dialog : : OnEntriesRemove ( )
{
QModelIndexList selection ( m_list - > selectionModel ( ) - > selectedRows ( ) ) ;
2019-06-01 15:25:33 +02:00
if ( selection . empty ( ) )
2017-10-24 17:09:38 +02:00
{
return ;
}
if ( selection . size ( ) = = 1 )
{
OnEntryRemove ( ) ;
return ;
}
2018-02-10 15:00:06 +01:00
if ( QMessageBox : : question ( this , tr ( " Delete Confirmation " ) , tr ( " Are you sure you want to delete these %1 items? " ) . arg ( selection . size ( ) ) , QMessageBox : : Yes , QMessageBox : : No ) = = QMessageBox : : Yes )
2017-10-24 17:09:38 +02:00
{
2019-08-10 13:24:14 +02:00
std : : sort ( selection . rbegin ( ) , selection . rend ( ) ) ;
2017-10-24 17:09:38 +02:00
for ( QModelIndex index : selection )
{
2019-08-10 13:50:27 +02:00
QTableWidgetItem * item = m_list - > item ( index . row ( ) , 1 ) ;
if ( ! item )
{
continue ;
}
const int idx_real = item - > data ( Qt : : UserRole ) . toInt ( ) ;
2017-10-24 17:09:38 +02:00
fs : : remove_all ( m_dir + m_save_entries [ idx_real ] . dirName + " / " ) ;
m_list - > removeRow ( index . row ( ) ) ;
}
}
}
2019-05-24 23:54:14 +02:00
// Pop-up a small context-menu, being a replacement for save_data_manage_dialog
2017-08-14 02:17:45 +02:00
void save_manager_dialog : : ShowContextMenu ( const QPoint & pos )
{
int idx = m_list - > currentRow ( ) ;
2017-10-24 17:09:38 +02:00
if ( idx = = - 1 )
{
return ;
}
2017-08-14 02:17:45 +02:00
2019-11-05 17:53:08 +01:00
const bool selectedItems = m_list - > selectionModel ( ) - > selectedRows ( ) . size ( ) > 1 ;
2017-09-06 19:32:33 +02:00
QAction * removeAct = new QAction ( tr ( " &Remove " ) , this ) ;
2017-10-24 17:09:38 +02:00
QAction * showDirAct = new QAction ( tr ( " &Open Save Directory " ) , this ) ;
2017-08-14 02:17:45 +02:00
2019-11-05 17:53:08 +01:00
QMenu * menu = new QMenu ( ) ;
2017-08-14 02:17:45 +02:00
menu - > addAction ( removeAct ) ;
2017-10-24 17:09:38 +02:00
menu - > addAction ( showDirAct ) ;
2017-08-14 02:17:45 +02:00
2017-10-24 17:09:38 +02:00
showDirAct - > setEnabled ( ! selectedItems ) ;
2017-08-14 02:17:45 +02:00
removeAct - > setEnabled ( idx ! = - 1 ) ;
2017-10-24 17:09:38 +02:00
// Events
connect ( removeAct , & QAction : : triggered , this , & save_manager_dialog : : OnEntriesRemove ) ; // entriesremove handles case of one as well
2018-02-10 15:00:06 +01:00
connect ( showDirAct , & QAction : : triggered , [ = ] ( )
{
2019-08-10 13:50:27 +02:00
QTableWidgetItem * item = m_list - > item ( idx , 1 ) ;
if ( ! item )
{
return ;
}
const int idx_real = item - > data ( Qt : : UserRole ) . toInt ( ) ;
const QString path = qstr ( m_dir + m_save_entries [ idx_real ] . dirName + " / " ) ;
2017-10-24 17:09:38 +02:00
QDesktopServices : : openUrl ( QUrl ( " file:/// " + path ) ) ;
} ) ;
2017-08-14 02:17:45 +02:00
2019-11-05 17:53:08 +01:00
menu - > exec ( m_list - > viewport ( ) - > mapToGlobal ( pos ) ) ;
2017-08-14 02:17:45 +02:00
}
2017-11-22 12:11:59 +01:00
2022-02-02 15:36:15 +01:00
void save_manager_dialog : : SetIconSize ( int size )
{
m_icon_size = QSize ( size , size ) ;
UpdateIcons ( ) ;
m_gui_settings - > SetValue ( gui : : sd_icon_size , size ) ;
}
2018-05-18 09:58:04 +02:00
void save_manager_dialog : : closeEvent ( QCloseEvent * event )
2017-11-22 12:11:59 +01:00
{
m_gui_settings - > SetValue ( gui : : sd_geometry , saveGeometry ( ) ) ;
2018-05-18 09:58:04 +02:00
QDialog : : closeEvent ( event ) ;
2017-11-22 12:11:59 +01:00
}
2022-02-02 15:36:15 +01:00
void save_manager_dialog : : UpdateDetails ( )
{
int selected = m_list - > selectionModel ( ) - > selectedRows ( ) . size ( ) ;
if ( selected ! = 1 )
{
m_details_icon - > setPixmap ( QPixmap ( ) ) ;
m_details_subtitle - > setText ( " " ) ;
m_details_modified - > setText ( " " ) ;
m_details_details - > setText ( " " ) ;
m_details_note - > setText ( " " ) ;
if ( selected > 1 )
{
m_button_delete - > setDisabled ( false ) ;
m_details_title - > setText ( tr ( " %1 items selected " ) . arg ( selected ) ) ;
}
else
{
m_button_delete - > setDisabled ( true ) ;
m_details_title - > setText ( tr ( " Select an item to view details " ) ) ;
}
m_button_folder - > setDisabled ( true ) ;
}
else
{
const int row = m_list - > currentRow ( ) ;
2019-08-10 13:50:27 +02:00
QTableWidgetItem * item = m_list - > item ( row , 1 ) ;
QTableWidgetItem * icon_item = m_list - > item ( row , 0 ) ;
if ( ! item | | ! icon_item )
{
return ;
}
const int idx = item - > data ( Qt : : UserRole ) . toInt ( ) ;
2022-02-02 15:36:15 +01:00
const SaveDataEntry & save = m_save_entries [ idx ] ;
2019-08-10 13:50:27 +02:00
m_details_icon - > setPixmap ( icon_item - > data ( Qt : : UserRole ) . value < QPixmap > ( ) ) ;
2022-02-02 15:36:15 +01:00
m_details_title - > setText ( qstr ( save . title ) ) ;
m_details_subtitle - > setText ( qstr ( save . subtitle ) ) ;
m_details_modified - > setText ( tr ( " Last modified: %1 " ) . arg ( FormatTimestamp ( save . mtime ) ) ) ;
m_details_details - > setText ( tr ( " Details: \n " ) . append ( qstr ( save . details ) ) ) ;
QString note = tr ( " Note: \n " ) ;
QVariantMap map = m_gui_settings - > GetValue ( gui : : m_saveNotes ) . toMap ( ) ;
if ( map . contains ( qstr ( save . dirName ) ) )
note . append ( map [ qstr ( save . dirName ) ] . toString ( ) ) ;
m_details_note - > setText ( note ) ;
m_button_delete - > setDisabled ( false ) ;
m_button_folder - > setDisabled ( false ) ;
}
}