* Bugfix for Issue 850 - memorycards being deleted when swapping slots.

* Preliminary work done for Issue 735 : allowing specified custom memorycard filenames.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3869 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-10-04 17:12:28 +00:00
parent c7a929a530
commit e63314f545
7 changed files with 238 additions and 221 deletions

View File

@ -107,14 +107,32 @@ struct ParsedAssignmentString
ParsedAssignmentString( const wxString& src );
};
// --------------------------------------------------------------------------------------
// FastFormatAscii
// --------------------------------------------------------------------------------------
// Fast formatting of ASCII text. This class uses a process-wide format buffer that is
// allocated only once and grown to accommodate string formatting needs. The buffer is
// thread-safe. This technique reduces the overhead of formatting strings by eliminating
// most or all heap allocation actions.
// ======================================================================================
// FastFormatAscii / FastFormatUnicode (overview!)
// ======================================================================================
// Fast formatting of ASCII or Unicode text. These classes uses a series of thread-local
// format buffers that are allocated only once and grown to accommodate string formatting
// needs. Because the buffers are thread-local, no thread synch objects are required in
// order to format strings, allowing for multi-threaded string formatting operations to be
// performed with maximum efficiency. This class also reduces the overhead typically required
// to allocate string buffers off the heap.
//
// Drawbacks:
// * Some overhead is added to the creation and destruction of threads, however since thread
// construction is a typically slow process, and often avoided to begin with, this should
// be a sound trade-off.
//
// Notes:
// * conversion to wxString requires a heap allocation.
// * FastFormatUnicode can accept either UTF8 or UTF16/32 (wchar_t) input, but FastFormatAscii
// accepts Ascii/UTF8 only.
//
// --------------------------------------------------------------------------------------
// FastFormatAscii
// --------------------------------------------------------------------------------------
class FastFormatAscii
{
protected:
@ -127,6 +145,7 @@ public:
FastFormatAscii& Write( const char* fmt, ... );
FastFormatAscii& WriteV( const char* fmt, va_list argptr );
void Clear();
bool IsEmpty() const;
const char* c_str() const { return m_dest->GetPtr(); }
@ -136,6 +155,9 @@ public:
//operator wxString() const;
};
// --------------------------------------------------------------------------------------
// FastFormatUnicode
// --------------------------------------------------------------------------------------
class FastFormatUnicode
{
protected:
@ -151,6 +173,7 @@ public:
FastFormatUnicode& WriteV( const char* fmt, va_list argptr );
FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr );
void Clear();
bool IsEmpty() const;
const wxChar* c_str() const { return (const wxChar*)m_dest->GetPtr(); }

View File

@ -39,12 +39,17 @@ static const int MaxFormattedStringLength = 0x80000;
// --------------------------------------------------------------------------------------
// FastFormatBuffers
// --------------------------------------------------------------------------------------
template< typename CharType >
// This class provides a series of pre-allocated thread-local buffers for use by string
// formatting tools. These buffers are handed out in round-robin style and require *no*
// thread sync objects and avoid multi-thread contention completely -- allowing multiple
// threads to format complicated strings concurrently with maximum efficiency.
//
class FastFormatBuffers
{
DeclareNoncopyableObject(FastFormatBuffers);
protected:
typedef char CharType;
typedef SafeAlignedArray<CharType,16> BufferType;
static const uint BufferCount = 4;
@ -62,7 +67,7 @@ public:
for (uint i=0; i<BufferCount; ++i)
{
m_buffers[i].Name = wxsFormat(L"%s Formatting Buffer (slot%d)",
(sizeof(CharType)==1) ? L"Ascii" : L"Unicode", i);
(sizeof(CharType)==1) ? L"UTF8/Ascii" : L"Wide-char", i);
m_buffers[i].MakeRoomFor(1024);
m_buffers[i].ChunkSize = 2048;
}
@ -72,7 +77,11 @@ public:
virtual ~FastFormatBuffers() throw()
{
pxAssumeDev(m_curslot==0, "Dangling Ascii formatting buffer detected!");
pxAssumeDev(m_curslot==0,
wxsFormat(L"Dangling %s formatting buffer detected!",
(sizeof(CharType)==1) ? L"UTF8/Ascii" : L"Wide-char"
)
);
}
bool HasFreeBuffer() const
@ -139,7 +148,7 @@ public:
};
static bool buffer_is_avail = false;
static GlobalBufferManager< BaseTlsVariable< FastFormatBuffers< char > > > m_buffer_tls(buffer_is_avail);
static GlobalBufferManager< BaseTlsVariable< FastFormatBuffers > > m_buffer_tls(buffer_is_avail);
static __ri void format_that_ascii_mess( SafeArray<char>& buffer, uint writepos, const char* fmt, va_list argptr )
{
@ -217,10 +226,16 @@ SafeArray<char>* GetFormatBuffer( bool& deleteDest )
// --------------------------------------------------------------------------------------
// FastFormatUnicode (implementations)
// --------------------------------------------------------------------------------------
// [TODO] This class should actually be renamed to FastFormatNative or FastFormatString, and
// adopted to properly support 1-byte wxChar types (mostly requiring some changes to the
// WriteV functions). The current implementation is fine for wx2.8, which always defaults
// to wide-varieties of wxChar -- but wx3.0 will use UTF8 for linux distros, which will break
// this class nicely in its current state. --air
FastFormatUnicode::FastFormatUnicode()
{
m_dest = GetFormatBuffer(m_deleteDest);
((wxChar*)m_dest->GetPtr())[0] = 0;
Clear();
}
FastFormatUnicode::~FastFormatUnicode() throw()
@ -231,6 +246,11 @@ FastFormatUnicode::~FastFormatUnicode() throw()
m_buffer_tls.Get()->ReleaseBuffer();
}
void FastFormatUnicode::Clear()
{
((wxChar*)m_dest->GetPtr())[0] = 0;
}
FastFormatUnicode& FastFormatUnicode::WriteV( const char* fmt, va_list argptr )
{
wxString converted( fromUTF8(FastFormatAscii().WriteV( fmt, argptr )) );
@ -277,7 +297,7 @@ bool FastFormatUnicode::IsEmpty() const
FastFormatAscii::FastFormatAscii()
{
m_dest = GetFormatBuffer(m_deleteDest);
m_dest->GetPtr()[0] = 0;
Clear();
}
FastFormatAscii::~FastFormatAscii() throw()
@ -288,16 +308,16 @@ FastFormatAscii::~FastFormatAscii() throw()
m_buffer_tls.Get()->ReleaseBuffer();
}
void FastFormatAscii::Clear()
{
m_dest->GetPtr()[0] = 0;
}
const wxString FastFormatAscii::GetString() const
{
return fromAscii(m_dest->GetPtr());
}
/*FastFormatAscii::operator wxString() const
{
return fromAscii(m_dest->GetPtr());
}*/
FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr )
{
format_that_ascii_mess( *m_dest, strlen(m_dest->GetPtr()), fmt, argptr );

View File

@ -85,7 +85,6 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint
*this += s_padding | StdExpand();
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnOk_Click ) );
//Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnApply_Click ) );
}
wxDirName Dialogs::CreateMemoryCardDialog::GetPathToMcds() const
@ -93,7 +92,7 @@ wxDirName Dialogs::CreateMemoryCardDialog::GetPathToMcds() const
return m_filepicker ? (wxDirName)m_filepicker->GetPath() : m_mcdpath;
}
// When this GUI is moved itno the FileMemoryCard plugin (where it eventually belongs),
// When this GUI is moved into the FileMemoryCard plugin (where it eventually belongs),
// this function will be removed and the MemoryCardFile::Create() function will be used
// instead.
static bool CreateIt( const wxString& mcdFile, uint sizeInMB )
@ -120,6 +119,11 @@ static bool CreateIt( const wxString& mcdFile, uint sizeInMB )
void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt )
{
// Save status of the NTFS compress checkbox for future reference.
// [TODO] Remove g_Conf->McdCompressNTFS, and have this dialog load/save directly from the ini.
g_Conf->McdCompressNTFS = m_check_CompressNTFS->GetValue();
if( !CreateIt(
m_filepicker ? m_filepicker->GetPath() : (m_mcdpath + m_mcdfile).GetFullPath(),
m_radio_CardSize ? m_radio_CardSize->SelectedItem().SomeInt : 8
@ -138,9 +142,18 @@ void Dialogs::CreateMemoryCardDialog::CreateControls()
{
#ifdef __WXMSW__
m_check_CompressNTFS = new pxCheckBox( this,
_("Use NTFS compression on this card"),
_("Use NTFS compression when creating this card."),
GetMsg_McdNtfsCompress()
);
m_check_CompressNTFS->SetToolTip( pxE( ".Tooltip:ChangingNTFS",
L"NTFS compression can be changed manually at any time by using file properties from Windows Explorer."
)
);
// Initial value of the checkbox is saved between calls to the dialog box. If the user checks
// the option, it remains checked for future dialog. If the user unchecks it, ditto.
m_check_CompressNTFS->SetValue( g_Conf->McdCompressNTFS );
#endif
const RadioPanelItem tbl_CardSizes[] =

View File

@ -44,18 +44,11 @@ Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent)
)
);
#ifdef __WXMSW__
m_check_CompressNTFS = new pxCheckBox( this,
_("Enable NTFS Compression on all cards by default."),
GetMsg_McdNtfsCompress()
);
#endif
for( uint i=0; i<2; ++i )
{
m_check_Multitap[i] = new pxCheckBox( this, wxsFormat(_("Enable Multitap on Port %u"), i+1) );
m_check_Multitap[i] = new pxCheckBox( this, pxsFmt(_("Enable Multitap on Port %u"), i+1) );
m_check_Multitap[i]->SetClientData( (void*)i );
m_check_Multitap[i]->SetName(wxsFormat( L"CheckBox::Multitap%u", i ));
m_check_Multitap[i]->SetName(pxsFmt( L"CheckBox::Multitap%u", i ));
}
// ------------------------------
@ -68,9 +61,6 @@ Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent)
*this += 4;
*this += m_check_Ejection;
#ifdef __WXMSW__
*this += m_check_CompressNTFS;
#endif
}
void Panels::McdConfigPanel_Toggles::Apply()
@ -79,9 +69,6 @@ void Panels::McdConfigPanel_Toggles::Apply()
g_Conf->EmuOptions.MultitapPort1_Enabled = m_check_Multitap[1]->GetValue();
g_Conf->EmuOptions.McdEnableEjection = m_check_Ejection->GetValue();
#ifdef __WXMSW__
g_Conf->McdCompressNTFS = m_check_CompressNTFS->GetValue();
#endif
}
void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
@ -90,10 +77,6 @@ void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
m_check_Multitap[1] ->SetValue( g_Conf->EmuOptions.MultitapPort1_Enabled );
m_check_Ejection ->SetValue( g_Conf->EmuOptions.McdEnableEjection );
#ifdef __WXMSW__
m_check_CompressNTFS->SetValue( g_Conf->McdCompressNTFS );
#endif
}
@ -104,7 +87,7 @@ Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
: BaseConfigurationDialog( parent, _("MemoryCard Manager"), 600 )
{
m_panel_mcdlist = new MemoryCardListPanel_Simple( this );
// [TODO] : Plan here is to add an advanced tab which gives the user the ability
// to configure the names of each memory card slot.
@ -122,7 +105,7 @@ Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
for( uint i=0; i<2; ++i )
{
if( pxCheckBox* check = (pxCheckBox*)FindWindow(wxsFormat( L"CheckBox::Multitap%u", i )) )
if( pxCheckBox* check = (pxCheckBox*)FindWindow(pxsFmt( L"CheckBox::Multitap%u", i )) )
Connect( check->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(McdConfigDialog::OnMultitapClicked) );
}

View File

@ -16,16 +16,17 @@
#include "PrecompiledHeader.h"
#include "AppCoreThread.h"
#include "System.h"
#include "MemoryCardFile.h"
#include "ConfigurationPanels.h"
#include "MemoryCardPanels.h"
#include "Dialogs/ConfigurationDialog.h"
#include "Utilities/IniInterface.h"
#include <wx/filepicker.h>
#include <wx/ffile.h>
#include <wx/dir.h>
#include "Dialogs/ConfigurationDialog.h"
#include "MemoryCardFile.h"
using namespace pxSizerFlags;
@ -175,6 +176,27 @@ void Panels::BaseMcdListPanel::CreateLayout()
*this += s_buttons | pxExpand;
*s_leftside_buttons += m_btn_Refresh;
if (m_listview)
{
IniLoader loader;
ScopedIniGroup group( loader, L"MemoryCardListPanel" );
m_listview->LoadSaveColumns( loader );
}
}
void Panels::BaseMcdListPanel::Apply()
{
// Save column widths to the configuration file. Since these are used *only* by this
// dialog, we use a direct local ini save approach, instead of going through g_conf.
uint colcnt = m_listview->GetColumnCount();
if (m_listview)
{
IniSaver saver;
ScopedIniGroup group( saver, L"MemoryCardListPanel" );
m_listview->LoadSaveColumns(saver);
}
}
void Panels::BaseMcdListPanel::AppStatusEvent_OnSettingsApplied()
@ -340,7 +362,7 @@ public:
if( dest.IsPresent && dest.IsFormatted )
{
wxsFormat( pxE( ".Popup:Mcd:Overwrite",
pxsFmt( pxE( ".Popup:Mcd:Overwrite",
L"This will copy the contents of the memory card in slot %u over the memory card in slot %u. "
L"All data on the target slot will be lost. Are you sure?" ),
src.Slot, dest.Slot
@ -382,7 +404,7 @@ public:
// Neat trick to handle errors.
result = result && wxRenameFile( srcfile.GetFullPath(), tempname.GetFullPath(), true );
result = result && wxRenameFile( destfile.GetFullPath(), srcfile.GetFullPath(), false );
result = result && wxRenameFile( tempname.GetFullPath(), srcfile.GetFullPath(), true );
result = result && wxRenameFile( tempname.GetFullPath(), destfile.GetFullPath(), true );
}
else if( destExists )
{
@ -411,6 +433,7 @@ enum McdMenuId
{
McdMenuId_Create = 0x888,
McdMenuId_Mount,
McdMenuId_Relocate,
McdMenuId_RefreshList
};
@ -424,6 +447,7 @@ Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent
m_MultitapEnabled[1] = false;
m_listview = new MemoryCardListView_Simple(this);
m_listview->SetMinSize(wxSize(m_listview->GetMinWidth(), m_listview->GetCharHeight() * 8));
m_listview->SetDropTarget( new McdDropTarget(m_listview) );
m_button_Create = new wxButton(this, wxID_ANY, _("Create"));
@ -453,6 +477,7 @@ Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent
Connect( McdMenuId_Create, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateCard) );
Connect( McdMenuId_Mount, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard) );
Connect( McdMenuId_Relocate, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRelocateCard) );
Connect( McdMenuId_RefreshList, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRefreshSelections) );
}
@ -491,7 +516,7 @@ void Panels::MemoryCardListPanel_Simple::UpdateUI()
void Panels::MemoryCardListPanel_Simple::Apply()
{
//_parent::Apply();
_parent::Apply();
ScopedCoreThreadClose closed_core;
closed_core.AllowResume();
@ -547,9 +572,8 @@ void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt)
{
ScopedCoreThreadClose closed_core;
const int sel = m_listview->GetFirstSelected();
if( wxNOT_FOUND == sel ) return;
const uint slot = sel;
const int slot = m_listview->GetFirstSelected();
if( wxNOT_FOUND == slot ) return;
if( m_Cards[slot].IsPresent )
{
@ -592,15 +616,30 @@ void Panels::MemoryCardListPanel_Simple::OnMountCard(wxCommandEvent& evt)
{
evt.Skip();
const int sel = m_listview->GetFirstSelected();
if( wxNOT_FOUND == sel ) return;
const uint slot = sel;
const int slot = m_listview->GetFirstSelected();
if( wxNOT_FOUND == slot ) return;
m_Cards[slot].IsEnabled = !m_Cards[slot].IsEnabled;
m_listview->RefreshItem(slot);
UpdateUI();
}
void Panels::MemoryCardListPanel_Simple::OnRelocateCard(wxCommandEvent& evt)
{
evt.Skip();
const int slot = m_listview->GetFirstSelected();
if( wxNOT_FOUND == slot ) return;
// Issue a popup to the user that allows them to pick a new .PS2 file to serve as
// the new host memorycard file for the slot. The dialog has a number of warnings
// present to reiterate that this is an advanced operation that PCSX2 may not
// support very well (ie, might be buggy).
m_listview->RefreshItem(slot);
UpdateUI();
}
void Panels::MemoryCardListPanel_Simple::OnListDrag(wxListEvent& evt)
{
int selection = m_listview->GetFirstSelected();
@ -628,8 +667,9 @@ void Panels::MemoryCardListPanel_Simple::OnOpenItemContextMenu(wxListEvent& evt)
{
const McdListItem& item( m_Cards[idx] );
junk->Append( McdMenuId_Create, item.IsPresent ? _("Delete") : _("Create new...") );
junk->Append( McdMenuId_Mount, item.IsEnabled ? _("Disable") : _("Enable") );
junk->Append( McdMenuId_Create, item.IsPresent ? _("Delete") : _("Create new...") );
junk->Append( McdMenuId_Mount, item.IsEnabled ? _("Disable") : _("Enable") );
junk->Append( McdMenuId_Relocate, _("Relocate file...") );
junk->AppendSeparator();
}

View File

@ -19,9 +19,53 @@
#include "Dialogs/ConfigurationDialog.h"
#include "Utilities/IniInterface.h"
using namespace pxSizerFlags;
using namespace Panels;
// --------------------------------------------------------------------------------------
// BaseMcdListView (implementations)
// --------------------------------------------------------------------------------------
void BaseMcdListView::SetMcdProvider( IMcdList* face )
{
m_CardProvider = face;
SetCardCount( m_CardProvider ? m_CardProvider->GetLength() : 0 );
}
const IMcdList& BaseMcdListView::GetMcdProvider() const
{
pxAssume( m_CardProvider );
return *m_CardProvider;
}
void BaseMcdListView::SetTargetedItem( int sel )
{
if( m_TargetedItem == sel ) return;
if( m_TargetedItem >= 0 ) RefreshItem( m_TargetedItem );
m_TargetedItem = sel;
RefreshItem( sel );
}
void BaseMcdListView::LoadSaveColumns( IniInterface& ini )
{
FastFormatUnicode label;
uint colcnt = GetColumnCount();
for( uint col=0; col<colcnt; ++col )
{
const ListViewColumnInfo& cinfo = GetDefaultColumnInfo(col);
label.Clear();
label.Write( L"ColumnWidth_%s", cinfo.name );
int width = GetColumnWidth(col);
ini.Entry( label, width, cinfo.width );
if (ini.IsLoading())
SetColumnWidth(col, width);
}
}
// --------------------------------------------------------------------------------------
// MemoryCardListView_Simple (implementations)
// --------------------------------------------------------------------------------------
@ -33,37 +77,45 @@ enum McdColumnType_Simple
McdColS_Formatted,
McdColS_DateModified,
McdColS_DateCreated,
McdColS_Filename,
McdColS_Count
};
MemoryCardListView_Simple::MemoryCardListView_Simple( wxWindow* parent )
: _parent( parent )
{
// I'd love to put this in the base class, and use the virtual GetDefaultColumnInfo method, but
// you can't call virtual functions from constructors in C++ reliably. -_- --air
CreateColumns();
}
void MemoryCardListView_Simple::CreateColumns()
{
struct ColumnInfo
{
wxString name;
wxListColumnFormat align;
};
const ColumnInfo columns[] =
{
{ _("Slot"), wxLIST_FORMAT_LEFT },
{ _("Status"), wxLIST_FORMAT_CENTER },
{ _("Size"), wxLIST_FORMAT_LEFT },
{ _("Formatted"), wxLIST_FORMAT_CENTER },
{ _("Modified"), wxLIST_FORMAT_LEFT },
{ _("Created On"), wxLIST_FORMAT_LEFT },
};
for( int i=0; i<McdColS_Count; ++i )
InsertColumn( i, columns[i].name, columns[i].align, -1 );
{
const ListViewColumnInfo& info = GetDefaultColumnInfo(i);
InsertColumn( i, pxGetTranslation(info.name), info.align, info.width );
}
}
const ListViewColumnInfo& MemoryCardListView_Simple::GetDefaultColumnInfo( uint idx ) const
{
static const ListViewColumnInfo columns[] =
{
{ L"Slot", 48, wxLIST_FORMAT_CENTER },
{ L"Status", 96, wxLIST_FORMAT_CENTER },
{ L"Size", 72, wxLIST_FORMAT_LEFT },
{ L"Formatted", 96, wxLIST_FORMAT_CENTER },
{ L"Modified", 120, wxLIST_FORMAT_LEFT },
{ L"Created", 120, wxLIST_FORMAT_LEFT },
{ L"Filename", 256, wxLIST_FORMAT_LEFT },
};
pxAssumeDev( idx < ArraySize(columns), "ListView column index is out of bounds." );
return columns[idx];
}
void MemoryCardListView_Simple::SetCardCount( int length )
{
if( !m_CardProvider ) length = 0;
@ -80,12 +132,22 @@ wxString MemoryCardListView_Simple::OnGetItemText(long item, long column) const
switch( column )
{
case McdColS_PortSlot: return wxsFormat( L"%u", item+1);
case McdColS_PortSlot: return pxsFmt( L"%u", item+1);
case McdColS_Status: return it.IsPresent ? ( it.IsEnabled ? _("Enabled") : _("Disabled")) : _("Missing");
case McdColS_Size: return it.IsPresent ? wxsFormat( L"%u MB", it.SizeInMB ) : (wxString)_("N/A");
case McdColS_Size: return it.IsPresent ? pxsFmt( L"%u MB", it.SizeInMB ) : (wxString)_("N/A");
case McdColS_Formatted: return it.IsFormatted ? _("Yes") : _("No");
case McdColS_DateModified: return it.IsPresent ? it.DateModified.FormatDate() : (wxString)_("N/A");
case McdColS_DateCreated: return it.IsPresent ? it.DateCreated.FormatDate() : (wxString)_("N/A");
case McdColS_Filename:
{
wxDirName filepath( it.Filename.GetPath() );
if (filepath.SameAs(g_Conf->Folders.MemoryCards))
return it.Filename.GetFullName();
else
return it.Filename.GetFullPath();
}
}
pxFail( "Unknown column index in MemoryCardListView -- returning an empty string." );
@ -127,101 +189,3 @@ wxListItemAttr* MemoryCardListView_Simple::OnGetItemAttr(long item) const
return &m_ItemAttr;
}
// --------------------------------------------------------------------------------------
// MemoryCardListView_Advanced (implementations)
// --------------------------------------------------------------------------------------
enum McdColumnType_Advanced
{
McdColA_Filename,
McdColA_Mounted,
McdColA_Size,
McdColA_Formatted,
McdColA_DateModified,
McdColA_DateCreated,
McdColA_Count
};
MemoryCardListView_Advanced::MemoryCardListView_Advanced( wxWindow* parent )
: _parent( parent )
{
CreateColumns();
}
void MemoryCardListView_Advanced::CreateColumns()
{
struct ColumnInfo
{
wxString name;
wxListColumnFormat align;
};
const ColumnInfo columns[] =
{
{ _("Filename"), wxLIST_FORMAT_LEFT },
{ _("Mounted"), wxLIST_FORMAT_CENTER },
{ _("Size"), wxLIST_FORMAT_LEFT },
{ _("Formatted"), wxLIST_FORMAT_CENTER },
{ _("Last Modified"), wxLIST_FORMAT_LEFT },
{ _("Created On"), wxLIST_FORMAT_LEFT },
//{ _("Path"), wxLIST_FORMAT_LEFT }
};
for( int i=0; i<McdColA_Count; ++i )
InsertColumn( i, columns[i].name, columns[i].align, -1 );
}
void MemoryCardListView_Advanced::SetCardCount( int length )
{
if( !m_CardProvider ) length = 0;
SetItemCount( length );
Refresh();
}
// return the text for the given column of the given item
wxString MemoryCardListView_Advanced::OnGetItemText(long item, long column) const
{
if( !m_CardProvider ) return _parent::OnGetItemText(item, column);
const McdListItem& it( m_CardProvider->GetCard(item) );
switch( column )
{
case McdColA_Mounted:
{
if( !it.IsEnabled ) return _("No");
return wxsFormat( L"%u", it.Slot+1);
}
case McdColA_Filename: return it.Filename.GetName();
case McdColA_Size: return wxsFormat( L"%u MB", it.SizeInMB );
case McdColA_Formatted: return it.IsFormatted ? L"Yes" : L"No";
case McdColA_DateModified: return it.DateModified.FormatDate();
case McdColA_DateCreated: return it.DateModified.FormatDate();
}
pxFail( "Unknown column index in MemoryCardListView_Advanced -- returning an empty string." );
return wxEmptyString;
}
// return the icon for the given item. In report view, OnGetItemImage will
// only be called for the first column. See OnGetItemColumnImage for
// details.
int MemoryCardListView_Advanced::OnGetItemImage(long item) const
{
return _parent::OnGetItemImage( item );
}
// return the icon for the given item and column.
int MemoryCardListView_Advanced::OnGetItemColumnImage(long item, long column) const
{
return _parent::OnGetItemColumnImage( item, column );
}
// return the attribute for the item (may return NULL if none)
wxListItemAttr* MemoryCardListView_Advanced::OnGetItemAttr(long item) const
{
wxListItemAttr* retval = _parent::OnGetItemAttr(item);
//const McdListItem& it( (*m_KnownCards)[item] );
return retval;
}

View File

@ -21,7 +21,7 @@
#include <wx/listctrl.h>
// --------------------------------------------------------------------------------------
// McdListItem
// McdListItem / IMcdList
// --------------------------------------------------------------------------------------
struct McdListItem
{
@ -67,6 +67,16 @@ public:
virtual wxDirName GetMcdPath() const=0;
};
struct ListViewColumnInfo
{
const wxChar* name;
int width;
wxListColumnFormat align;
};
// --------------------------------------------------------------------------------------
// BaseMcdListView
// --------------------------------------------------------------------------------------
class BaseMcdListView : public wxListView
{
typedef wxListView _parent;
@ -86,27 +96,13 @@ public:
}
virtual void SetCardCount( int length )=0;
virtual void SetMcdProvider( IMcdList* face );
virtual void SetMcdProvider( IMcdList* face )
{
m_CardProvider = face;
SetCardCount( m_CardProvider ? m_CardProvider->GetLength() : 0 );
}
virtual const IMcdList& GetMcdProvider() const
{
pxAssume( m_CardProvider );
return *m_CardProvider;
}
virtual void SetTargetedItem( int sel )
{
if( m_TargetedItem == sel ) return;
virtual void LoadSaveColumns( IniInterface& ini );
virtual const ListViewColumnInfo& GetDefaultColumnInfo( uint idx ) const=0;
if( m_TargetedItem >= 0 ) RefreshItem( m_TargetedItem );
m_TargetedItem = sel;
RefreshItem( sel );
}
virtual const IMcdList& GetMcdProvider() const;
virtual void SetTargetedItem( int sel );
};
// --------------------------------------------------------------------------------------
@ -121,7 +117,9 @@ public:
MemoryCardListView_Simple( wxWindow* parent );
void CreateColumns();
virtual void SetCardCount( int length );
virtual const ListViewColumnInfo& GetDefaultColumnInfo( uint idx ) const;
protected:
// Overrides for wxLC_VIRTUAL
@ -132,28 +130,6 @@ protected:
};
// --------------------------------------------------------------------------------------
// MemoryCardListView_Advanced
// --------------------------------------------------------------------------------------
class MemoryCardListView_Advanced : public BaseMcdListView
{
typedef BaseMcdListView _parent;
public:
virtual ~MemoryCardListView_Advanced() throw() { }
MemoryCardListView_Advanced( wxWindow* parent );
void CreateColumns();
virtual void SetCardCount( int length );
protected:
// Overrides for wxLC_VIRTUAL
virtual wxString OnGetItemText(long item, long column) const;
virtual int OnGetItemImage(long item) const;
virtual int OnGetItemColumnImage(long item, long column) const;
virtual wxListItemAttr *OnGetItemAttr(long item) const;
};
namespace Panels
{
// --------------------------------------------------------------------------------------
@ -195,7 +171,8 @@ namespace Panels
RefreshMcds();
}
void AppStatusEvent_OnSettingsApplied();
virtual void Apply();
virtual void AppStatusEvent_OnSettingsApplied();
};
// --------------------------------------------------------------------------------------
@ -230,11 +207,12 @@ namespace Panels
protected:
void OnCreateCard(wxCommandEvent& evt);
void OnMountCard(wxCommandEvent& evt);
void OnRelocateCard(wxCommandEvent& evt);
void OnListDrag(wxListEvent& evt);
void OnListSelectionChanged(wxListEvent& evt);
void OnOpenItemContextMenu(wxListEvent& evt);
virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames);
virtual void Apply();
@ -254,10 +232,6 @@ namespace Panels
pxCheckBox* m_check_Multitap[2];
pxCheckBox* m_check_Ejection;
#ifdef __WXMSW__
pxCheckBox* m_check_CompressNTFS;
#endif
public:
McdConfigPanel_Toggles( wxWindow* parent );
virtual ~McdConfigPanel_Toggles() throw() { }