mirror of https://github.com/PCSX2/pcsx2.git
Memory card manager: should be functionally complete. Feedback will be appreciated.
Major new: insert-from/remove-to file system files. New: context menu and buttons for the new functionality (including copy which was only available via drag and drop). Mod: slight text changes (finally should be ready for translations). Mod: slight cleanup of functionality: - 'Copy' changed to 'Duplicate', and can be invoked on any card, or via drag and drop to an empty port. - drag and drop of cards: from a port to the filesystem = eject card (not swap). - drag and drop of cards: from the filesystem to a port = insert the card to the port. While it's functionally complete (I hope), I'm not 100% happy with the GUI. Better GUI would have been 2 separate lists (ps2 ports, unused cards) and cards can be moved between the lists. However, creating another list control, laying it out and handling the interactions between the two lists would have been a headache (even more than it already was). The major case which is hampered by the combined list is when the user has many cards on the filesystem, and he wants to insert it to a port, but the ports are way up the list so a scroll is required. This case is handled by the "Insert card" button which is available for any card on the filesystem (prompts the user to select a target port). Let me know what you think. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4447 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
c704b89cd1
commit
269f030778
|
@ -721,7 +721,7 @@ void InitializeSIO(u8 value)
|
||||||
wxTimeSpan delta = wxDateTime::UNow().Subtract( m_ForceEjection_minTriesTimestamp[port] );
|
wxTimeSpan delta = wxDateTime::UNow().Subtract( m_ForceEjection_minTriesTimestamp[port] );
|
||||||
if ( delta.GetMilliseconds() >= FORCED_MCD_EJECTION_MAX_MS_AFTER_MIN_TRIES )
|
if ( delta.GetMilliseconds() >= FORCED_MCD_EJECTION_MAX_MS_AFTER_MIN_TRIES )
|
||||||
{
|
{
|
||||||
Console.Warning( L"[%s] Auto-eject: Timeout reached after mcd was accessed %d times [port:%d, slot:%d]", GetTimeMsStr().c_str(), numTimesAccessed, port, slot);
|
DevCon.Warning( L"[%s] Auto-eject: Timeout reached after mcd was accessed %d times [port:%d, slot:%d]", GetTimeMsStr().c_str(), numTimesAccessed, port, slot);
|
||||||
m_ForceEjectionTimeout[port] = 0; //Done. on next sio access the card will be seen as inserted.
|
m_ForceEjectionTimeout[port] = 0; //Done. on next sio access the card will be seen as inserted.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ wxFilePickerCtrl* CreateMemoryCardFilePicker( wxWindow* parent, uint portidx, ui
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, const wxDirName& mcdpath, const wxString& suggested_mcdfileName)
|
Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, const wxDirName& mcdpath, const wxString& suggested_mcdfileName)
|
||||||
: wxDialogWithHelpers( parent, _("Create a new memory card file") )
|
: wxDialogWithHelpers( parent, _("Create a new memory card") )
|
||||||
, m_mcdpath( mcdpath )
|
, m_mcdpath( mcdpath )
|
||||||
, m_mcdfile( suggested_mcdfileName )//suggested_and_result_mcdfileName.IsEmpty() ? g_Conf->Mcd[slot].Filename.GetFullName()
|
, m_mcdfile( suggested_mcdfileName )//suggested_and_result_mcdfileName.IsEmpty() ? g_Conf->Mcd[slot].Filename.GetFullName()
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, const
|
||||||
// s_padding += m_filepicker | StdExpand();
|
// s_padding += m_filepicker | StdExpand();
|
||||||
// else
|
// else
|
||||||
{
|
{
|
||||||
s_padding += Heading( _( "New memory card file:" ) ) | StdExpand();
|
s_padding += Heading( _( "New memory card:" ) ) | StdExpand();
|
||||||
s_padding += Heading( wxString(_("At folder: ")) + (m_mcdpath + m_mcdfile).GetPath() ).Unwrapped() | StdExpand();
|
s_padding += Heading( wxString(_("At folder: ")) + (m_mcdpath + m_mcdfile).GetPath() ).Unwrapped() | StdExpand();
|
||||||
|
|
||||||
wxBoxSizer& s_filename( *new wxBoxSizer(wxHORIZONTAL) );
|
wxBoxSizer& s_filename( *new wxBoxSizer(wxHORIZONTAL) );
|
||||||
|
@ -115,7 +115,7 @@ bool Dialogs::CreateMemoryCardDialog::CreateIt( const wxString& mcdFile, uint si
|
||||||
u8 m_effeffs[528*16];
|
u8 m_effeffs[528*16];
|
||||||
memset8<0xff>( m_effeffs );
|
memset8<0xff>( m_effeffs );
|
||||||
|
|
||||||
Console.WriteLn( L"(FileMcd) Creating new %uMB memory card file: '%s'", sizeInMB, mcdFile.c_str() );
|
Console.WriteLn( L"(FileMcd) Creating new %uMB memory card: '%s'", sizeInMB, mcdFile.c_str() );
|
||||||
|
|
||||||
wxFFile fp( mcdFile, L"wb" );
|
wxFFile fp( mcdFile, L"wb" );
|
||||||
if( !fp.IsOpened() ) return false;
|
if( !fp.IsOpened() ) return false;
|
||||||
|
@ -147,7 +147,7 @@ void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
wxString message;
|
wxString message;
|
||||||
message.Printf(_("Error (%s)"), errMsg.c_str());
|
message.Printf(_("Error (%s)"), errMsg.c_str());
|
||||||
Msgbox::Alert( message, _("Create memory card file") );
|
Msgbox::Alert( message, _("Create memory card") );
|
||||||
m_text_filenameInput->SetFocus();
|
m_text_filenameInput->SetFocus();
|
||||||
m_text_filenameInput->SelectAll();
|
m_text_filenameInput->SelectAll();
|
||||||
return;
|
return;
|
||||||
|
@ -160,8 +160,8 @@ void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt )
|
||||||
) )
|
) )
|
||||||
{
|
{
|
||||||
Msgbox::Alert(
|
Msgbox::Alert(
|
||||||
_("Error: The memory card file could not be created."),
|
_("Error: The memory card could not be created."),
|
||||||
_("Create memory card file")
|
_("Create memory card")
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,8 +109,8 @@ Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
|
||||||
|
|
||||||
wxBoxSizer* s_top = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* s_top = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
wxString title=_("Drag card files in the list to swap or copy between ports.");
|
wxString title=_("Drag cards to or from PS2-ports");
|
||||||
title+=_("\nNote: Rename/Copy/Create/Delete will NOT be reverted with 'Cancel'.");
|
title+=_("\nNote: Rename/Duplicate/Create/Delete will NOT be reverted with 'Cancel'.");
|
||||||
|
|
||||||
*s_top += Heading(title) | StdExpand();
|
*s_top += Heading(title) | StdExpand();
|
||||||
*s_top += StdPadding;
|
*s_top += StdPadding;
|
||||||
|
|
|
@ -180,7 +180,7 @@ void FileMemoryCard::Open()
|
||||||
if( !Create( str, 8 ) )
|
if( !Create( str, 8 ) )
|
||||||
{
|
{
|
||||||
Msgbox::Alert(
|
Msgbox::Alert(
|
||||||
wxsFormat(_( "Could not create a memory card file: \n\n%s\n\n" ), str.c_str()) +
|
wxsFormat(_( "Could not create a memory card: \n\n%s\n\n" ), str.c_str()) +
|
||||||
GetDisabledMessage( slot )
|
GetDisabledMessage( slot )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ void FileMemoryCard::Open()
|
||||||
// Translation note: detailed description should mention that the memory card will be disabled
|
// Translation note: detailed description should mention that the memory card will be disabled
|
||||||
// for the duration of this session.
|
// for the duration of this session.
|
||||||
Msgbox::Alert(
|
Msgbox::Alert(
|
||||||
wxsFormat(_( "Access denied to memory card file: \n\n%s\n\n" ), str.c_str()) +
|
wxsFormat(_( "Access denied to memory card: \n\n%s\n\n" ), str.c_str()) +
|
||||||
GetDisabledMessage( slot )
|
GetDisabledMessage( slot )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,7 +264,7 @@ public:
|
||||||
if( !pxAssertDev( len == sizeof(u32), "Data length mismatch on memory card drag&drop operation." ) ) return false;
|
if( !pxAssertDev( len == sizeof(u32), "Data length mismatch on memory card drag&drop operation." ) ) return false;
|
||||||
|
|
||||||
m_viewIndex = *(u32*)buf;
|
m_viewIndex = *(u32*)buf;
|
||||||
return ( (uint)m_viewIndex < 8 ); // sanity check (unsigned, so that -1 also is invalid) :)
|
return true;//( (uint)m_viewIndex < 8 ); // sanity check (unsigned, so that -1 also is invalid) :)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must provide overloads to avoid hiding them (and warnings about it)
|
// Must provide overloads to avoid hiding them (and warnings about it)
|
||||||
|
@ -284,6 +284,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class McdDropTarget : public wxDropTarget
|
class McdDropTarget : public wxDropTarget
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -368,141 +369,68 @@ public:
|
||||||
virtual wxDragResult OnDropMcd( McdSlotItem& src, McdSlotItem& dest, wxDragResult def )
|
virtual wxDragResult OnDropMcd( McdSlotItem& src, McdSlotItem& dest, wxDragResult def )
|
||||||
{
|
{
|
||||||
if( src.Slot == dest.Slot ) return wxDragNone;
|
if( src.Slot == dest.Slot ) return wxDragNone;
|
||||||
if( !pxAssert( (src.Slot >= 0) && (dest.Slot >= 0) ) ) return wxDragNone;
|
//if( !pxAssert( (src.Slot >= 0) && (dest.Slot >= 0) ) ) return wxDragNone;
|
||||||
const wxDirName basepath( m_listview->GetMcdProvider().GetMcdPath() );
|
const wxDirName basepath( m_listview->GetMcdProvider().GetMcdPath() );
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
if( wxDragCopy == def )
|
if( wxDragCopy == def )
|
||||||
{
|
{
|
||||||
// user is force invoking copy mode, which means we need to check the destination
|
if( !m_listview->GetMcdProvider().UiDuplicateCard(src, dest) )
|
||||||
// and prompt if it looks valuable (formatted).
|
|
||||||
if( !src.IsPresent )
|
|
||||||
{
|
|
||||||
Msgbox::Alert(_("Failed. Can only copy an existing card file."), _("Copy memory card file"));
|
|
||||||
return wxDragNone;
|
return wxDragNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !dest.IsPresent )
|
|
||||||
{
|
|
||||||
while (1){
|
|
||||||
wxString newFilename=L"";
|
|
||||||
newFilename = wxGetTextFromUser(_("Select a name for the new memory card file copy\n( '.ps2' will be added automatically)"), _("Copy memory card file"));
|
|
||||||
if( newFilename==L"" )
|
|
||||||
{
|
|
||||||
Msgbox::Alert( _("Copy canceled"), _("Copy memory card file") );
|
|
||||||
return wxDragNone;
|
|
||||||
}
|
|
||||||
newFilename += L".ps2";
|
|
||||||
|
|
||||||
//check that the name is valid for a new file
|
|
||||||
wxString errMsg;
|
|
||||||
if( !isValidNewFilename( newFilename, basepath, errMsg, 5 ) )
|
|
||||||
{
|
|
||||||
wxString message;
|
|
||||||
message.Printf(_("Error (%s)"), errMsg.c_str());
|
|
||||||
Msgbox::Alert( message, _("Copy memory card file") );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest.Filename = newFilename;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
wxFileName srcfile( basepath + src.Filename);//g_Conf->Mcd[src.Slot].Filename );
|
|
||||||
wxFileName destfile( basepath + dest.Filename);//g_Conf->Mcd[dest.Slot].Filename );
|
|
||||||
|
|
||||||
if( dest.IsPresent && dest.IsFormatted )
|
|
||||||
{
|
|
||||||
wxString content;
|
|
||||||
content.Printf(
|
|
||||||
pxE( "!Notice:Mcd:Overwrite",
|
|
||||||
L"This will copy the entire contents of memory card file '%s' [=slot %u] to the memory card file '%s' [=slot %u]. "
|
|
||||||
L"All previous data on memory card file '%s' will be lost. Are you sure?" ),
|
|
||||||
src.Filename.GetFullName().c_str(), src.Slot,
|
|
||||||
dest.Filename.GetFullName().c_str(), dest.Slot,
|
|
||||||
dest.Filename.GetFullName().c_str(), dest.Slot
|
|
||||||
);
|
|
||||||
|
|
||||||
result = Msgbox::YesNo( content, _("Overwrite memory card file?") );
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
return wxDragNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedBusyCursor doh( Cursor_ReallyBusy );
|
|
||||||
if( !wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) )
|
|
||||||
{
|
|
||||||
wxString heading;
|
|
||||||
heading.Printf( pxE( "!Notice:Mcd:Copy Failed",
|
|
||||||
L"Error! Copy failed. Destination memory card file '%s' [=slot %u] is in use." ),
|
|
||||||
dest.Filename.GetFullName().c_str(), dest.Slot
|
|
||||||
);
|
|
||||||
|
|
||||||
wxString content;
|
|
||||||
|
|
||||||
Msgbox::Alert( heading + L"\n\n" + content, _("Copy failed!") );
|
|
||||||
return wxDragNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destination memcard isEnabled state is the same now as the source's
|
|
||||||
wxString success;
|
|
||||||
success.Printf(_("Memory card file '%s' copied to '%s'.\n\nBoth card files are now identical."),
|
|
||||||
src.Filename.GetFullName().c_str(),
|
|
||||||
dest.Filename.GetFullName().c_str()
|
|
||||||
);
|
|
||||||
Msgbox::Alert(success, _("Success"));
|
|
||||||
dest.IsPresent=true;
|
|
||||||
dest.IsEnabled = true;//src.IsEnabled;
|
|
||||||
m_listview->GetMcdProvider().PublicApply();
|
|
||||||
}
|
|
||||||
else if( wxDragMove == def )
|
else if( wxDragMove == def )
|
||||||
{// move/swap files in ports
|
{ // source can only be an existing card.
|
||||||
// Just swaps the assigned file names at the slots.
|
// if dest is a ps2-port (empty or not) -> swap cards between ports.
|
||||||
|
// is dest is a non-ps2-port -> remove card from port.
|
||||||
|
|
||||||
//Note: each slot has 2 important properties: IsPresent (with Filename) and IsEnabled.
|
// Note: For the sake of usability, automatically enable dest if a ps2-port.
|
||||||
// For the sake of usability, when draggind src to dest, if src IsPresent, automatically enable dest.
|
if (src.IsPresent)
|
||||||
// However, src slot keeps its old IsEnabled regardless of what happened.
|
|
||||||
if (src.IsPresent || dest.IsPresent)
|
|
||||||
{
|
{
|
||||||
//swap file names (along with IsPresent)
|
|
||||||
wxFileName tmpFilename = dest.Filename;
|
wxFileName tmpFilename = dest.Filename;
|
||||||
bool tmpPresent = dest.IsPresent;
|
bool tmpPresent = dest.IsPresent;
|
||||||
|
if (src.Slot<0 && m_listview->GetMcdProvider().isFileAssignedToInternalSlot(src.Filename))
|
||||||
|
m_listview->GetMcdProvider().RemoveCardFromSlot(src.Filename);
|
||||||
|
|
||||||
dest.Filename = src.Filename;
|
dest.Filename = src.Filename;
|
||||||
|
dest.IsEnabled = dest.IsPresent? dest.IsEnabled:true;
|
||||||
dest.IsPresent = src.IsPresent;
|
dest.IsPresent = src.IsPresent;
|
||||||
if( src.IsPresent )
|
|
||||||
dest.IsEnabled = true;
|
|
||||||
|
|
||||||
|
if (dest.Slot>=0)
|
||||||
|
{//2 internal slots: swap
|
||||||
src.Filename = tmpFilename;
|
src.Filename = tmpFilename;
|
||||||
src.IsPresent = tmpPresent;
|
src.IsPresent = tmpPresent;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{//dest is at the filesystem (= remove card from slot)
|
||||||
|
src.Filename = L"";
|
||||||
|
src.IsPresent = false;
|
||||||
|
src.IsEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum McdMenuId
|
enum McdMenuId
|
||||||
{
|
{
|
||||||
McdMenuId_Create = 0x888,
|
McdMenuId_Create = 0x888,
|
||||||
McdMenuId_Mount,
|
McdMenuId_Mount,
|
||||||
McdMenuId_Rename,
|
McdMenuId_Rename,
|
||||||
McdMenuId_RefreshList
|
McdMenuId_RefreshList,
|
||||||
|
McdMenuId_AssignUnassign,
|
||||||
|
McdMenuId_Duplicate,
|
||||||
};
|
};
|
||||||
|
|
||||||
// =====================================================================================================
|
|
||||||
// MemoryCardListPanel_Simple (implementations)
|
Panels::MemoryCardListPanel_Simple* g_uglyPanel=NULL;
|
||||||
// =====================================================================================================
|
void g_uglyFunc(){if (g_uglyPanel) g_uglyPanel->OnChangedListSelection();}
|
||||||
/* some code from cotton to enumerate files at a folder:
|
|
||||||
[21:07] <cotton> ScopedPtr<wxArrayString> memcardList(new wxArrayString());
|
Panels::MemoryCardListPanel_Simple::~MemoryCardListPanel_Simple() throw(){g_uglyPanel=NULL;}
|
||||||
[21:07] <cotton> wxDir::GetAllFiles(m_FolderPicker->GetPath().ToString(), memcardList, L"*.ps2*", wxDIR_FILES);
|
|
||||||
[21:07] <cotton> for(uint i = 0; i < memcardList->size(); i++) {
|
|
||||||
[21:07] <cotton> DevCon.WriteLn(L"hey - " + memcardList[0][i]);
|
|
||||||
[21:07] <cotton> }
|
|
||||||
*/
|
|
||||||
Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent )
|
Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent )
|
||||||
: _parent( parent )
|
: _parent( parent )
|
||||||
{
|
{
|
||||||
|
@ -511,18 +439,16 @@ Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent
|
||||||
|
|
||||||
m_listview = new MemoryCardListView_Simple(this);
|
m_listview = new MemoryCardListView_Simple(this);
|
||||||
|
|
||||||
// Fixme: Small problem:
|
m_listview->SetMinSize(wxSize(700, m_listview->GetCharHeight() * 13)); // 740 is nice for default font sizes
|
||||||
// m_listview->GetMinWidth() can return -1 (On Win7 x64 + Aero for example)
|
|
||||||
if ( m_listview->GetMinWidth() <= 0 )
|
|
||||||
m_listview->SetMinSize(wxSize(740, m_listview->GetCharHeight() * 14)); // 740 is nice for default font sizes
|
|
||||||
else
|
|
||||||
m_listview->SetMinSize(wxSize(m_listview->GetMinWidth(), m_listview->GetCharHeight() * 14));
|
|
||||||
|
|
||||||
m_listview->SetDropTarget( new McdDropTarget(m_listview) );
|
m_listview->SetDropTarget( new McdDropTarget(m_listview) );
|
||||||
|
|
||||||
m_button_Create = new wxButton(this, wxID_ANY, _("Create card file"));
|
|
||||||
m_button_Mount = new wxButton(this, wxID_ANY, _("Enable port"));
|
m_button_Mount = new wxButton(this, wxID_ANY, _("Enable port"));
|
||||||
m_button_Rename = new wxButton(this, wxID_ANY, _("Rename card file"));
|
|
||||||
|
m_button_AssignUnassign = new wxButton(this, wxID_ANY, _("Eject"));
|
||||||
|
m_button_Duplicate = new wxButton(this, wxID_ANY, _("Duplicate ..."));
|
||||||
|
m_button_Rename = new wxButton(this, wxID_ANY, _("Rename ..."));
|
||||||
|
m_button_Create = new wxButton(this, wxID_ANY, _("Create ..."));
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// Sizer / Layout Section
|
// Sizer / Layout Section
|
||||||
|
@ -534,8 +460,13 @@ Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent
|
||||||
*s_leftside_buttons += m_button_Mount;
|
*s_leftside_buttons += m_button_Mount;
|
||||||
*s_leftside_buttons += 20;
|
*s_leftside_buttons += 20;
|
||||||
|
|
||||||
*s_leftside_buttons += m_button_Rename;
|
*s_leftside_buttons += Text(_("Card: ")) | pxMiddle;
|
||||||
|
*s_leftside_buttons += m_button_AssignUnassign;
|
||||||
*s_leftside_buttons += 2;
|
*s_leftside_buttons += 2;
|
||||||
|
*s_leftside_buttons += m_button_Duplicate;
|
||||||
|
*s_leftside_buttons += 2;
|
||||||
|
*s_leftside_buttons += m_button_Rename;
|
||||||
|
*s_leftside_buttons += 8;
|
||||||
*s_leftside_buttons += m_button_Create;
|
*s_leftside_buttons += m_button_Create;
|
||||||
SetSizerAndFit(GetSizer());
|
SetSizerAndFit(GetSizer());
|
||||||
|
|
||||||
|
@ -553,12 +484,22 @@ Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent
|
||||||
Connect( m_button_Mount->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard));
|
Connect( m_button_Mount->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard));
|
||||||
Connect( m_button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateOrDeleteCard));
|
Connect( m_button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateOrDeleteCard));
|
||||||
Connect( m_button_Rename->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRenameFile));
|
Connect( m_button_Rename->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRenameFile));
|
||||||
|
Connect( m_button_Duplicate->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnDuplicateFile));
|
||||||
|
Connect( m_button_AssignUnassign->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnAssignUnassignFile));
|
||||||
|
|
||||||
// Popup Menu Connections!
|
// Popup Menu Connections!
|
||||||
Connect( McdMenuId_Create, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateOrDeleteCard) );
|
Connect( McdMenuId_Create, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateOrDeleteCard) );
|
||||||
Connect( McdMenuId_Mount, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard) );
|
Connect( McdMenuId_Mount, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard) );
|
||||||
Connect( McdMenuId_Rename, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRenameFile) );
|
Connect( McdMenuId_Rename, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRenameFile) );
|
||||||
|
Connect( McdMenuId_AssignUnassign, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnAssignUnassignFile) );
|
||||||
|
Connect( McdMenuId_Duplicate, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnDuplicateFile) );
|
||||||
|
|
||||||
Connect( McdMenuId_RefreshList, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRefreshSelections) );
|
Connect( McdMenuId_RefreshList, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRefreshSelections) );
|
||||||
|
|
||||||
|
//because the wxEVT_COMMAND_LIST_ITEM_DESELECTED doesn't work (buttons stay enabled when clicking an empty area of the list),
|
||||||
|
// m_listview can send us an event that indicates a change at the list. Ugly, but works.
|
||||||
|
g_uglyPanel=this;
|
||||||
|
m_listview->setExternHandler(g_uglyFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::MemoryCardListPanel_Simple::UpdateUI()
|
void Panels::MemoryCardListPanel_Simple::UpdateUI()
|
||||||
|
@ -572,27 +513,36 @@ void Panels::MemoryCardListPanel_Simple::UpdateUI()
|
||||||
m_button_Create->Disable();
|
m_button_Create->Disable();
|
||||||
m_button_Mount->Disable();
|
m_button_Mount->Disable();
|
||||||
m_button_Rename->Disable();
|
m_button_Rename->Disable();
|
||||||
|
m_button_Duplicate->Disable();
|
||||||
|
m_button_AssignUnassign->Disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const McdSlotItem& card( GetCardForViewIndex(sel) );
|
const McdSlotItem& card( GetCardForViewIndex(sel) );
|
||||||
|
|
||||||
m_button_Rename->Enable( card.IsPresent );
|
m_button_Rename->Enable( card.IsPresent );
|
||||||
wxString renameTip = _("Rename this memory card file.");
|
wxString renameTip = _("Rename this memory card ...");
|
||||||
renameTip += wxString(L"\n") + _("Note: Port needs to be disabled first, and the change then needs to be applied." );
|
|
||||||
pxSetToolTip( m_button_Rename, renameTip );
|
pxSetToolTip( m_button_Rename, renameTip );
|
||||||
|
|
||||||
m_button_Create->Enable();
|
m_button_AssignUnassign->Enable( card.IsPresent );
|
||||||
m_button_Create->SetLabel( card.IsPresent ? _("Delete card file") : _("Create card file") );
|
m_button_AssignUnassign->SetLabel( card.Slot>=0 ? _("Eject") : _("Insert ...") );
|
||||||
wxString deleteTip = _("Permanently delete this memory card file from disk (all contents are lost)");
|
wxString assignTip = (card.Slot>=0)?_("Eject the card from this port"):_("Insert this card to a port ...");
|
||||||
deleteTip += wxString(L"\n") + _("Note: Port needs to be disabled first, and the change then needs to be applied." );
|
pxSetToolTip( m_button_AssignUnassign, assignTip );
|
||||||
|
|
||||||
|
m_button_Duplicate->Enable( card.IsPresent );
|
||||||
|
wxString dupTip = _("Create a duplicate of this memory card ...");
|
||||||
|
pxSetToolTip( m_button_Duplicate, dupTip );
|
||||||
|
|
||||||
|
m_button_Create->Enable(card.Slot>=0 || card.IsPresent);
|
||||||
|
m_button_Create->SetLabel( card.IsPresent ? _("Delete") : _("Create ...") );
|
||||||
|
wxString deleteTip = _("Permanently delete this memory card from disk (all contents are lost)");
|
||||||
|
|
||||||
if (card.IsPresent)
|
if (card.IsPresent)
|
||||||
pxSetToolTip( m_button_Create, deleteTip);
|
pxSetToolTip( m_button_Create, deleteTip);
|
||||||
else
|
else
|
||||||
pxSetToolTip( m_button_Create, _("Create a new memory card file and assign it to the selected PS2-Port." ));
|
pxSetToolTip( m_button_Create, _("Create a new memory card and assign it to the selected PS2-Port." ));
|
||||||
|
|
||||||
m_button_Mount->Enable( card.IsPresent );
|
m_button_Mount->Enable( card.IsPresent && card.Slot>=0);
|
||||||
m_button_Mount->SetLabel( card.IsEnabled ? _("Disable Port") : _("Enable Port") );
|
m_button_Mount->SetLabel( card.IsEnabled ? _("Disable Port") : _("Enable Port") );
|
||||||
pxSetToolTip( m_button_Mount,
|
pxSetToolTip( m_button_Mount,
|
||||||
card.IsEnabled
|
card.IsEnabled
|
||||||
|
@ -643,7 +593,7 @@ void Panels::MemoryCardListPanel_Simple::AppStatusEvent_OnSettingsApplied()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.Error( L"memcard was enabled but had an invalid file name. Aborting automatic creation. Hope for the best..." );
|
Console.Error( L"memcard was enabled but had an invalid file name. Aborting automatic creation. Hope for the best... (%s)", errMsg.c_str() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,8 +626,8 @@ void Panels::MemoryCardListPanel_Simple::DoRefresh()
|
||||||
{
|
{
|
||||||
for( uint slot=0; slot<8; ++slot )
|
for( uint slot=0; slot<8; ++slot )
|
||||||
{
|
{
|
||||||
if( FileMcd_IsMultitapSlot(slot) && !m_MultitapEnabled[FileMcd_GetMtapPort(slot)] )
|
//if( FileMcd_IsMultitapSlot(slot) && !m_MultitapEnabled[FileMcd_GetMtapPort(slot)] )
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
//wxFileName fullpath( m_FolderPicker->GetPath() + g_Conf->Mcd[slot].Filename.GetFullName() );
|
//wxFileName fullpath( m_FolderPicker->GetPath() + g_Conf->Mcd[slot].Filename.GetFullName() );
|
||||||
wxFileName fullpath = m_FolderPicker->GetPath() + m_Cards[slot].Filename.GetFullName();
|
wxFileName fullpath = m_FolderPicker->GetPath() + m_Cards[slot].Filename.GetFullName();
|
||||||
|
@ -686,10 +636,18 @@ void Panels::MemoryCardListPanel_Simple::DoRefresh()
|
||||||
m_Cards[slot].Slot = slot;
|
m_Cards[slot].Slot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReadFilesAtMcdFolder();
|
||||||
|
|
||||||
|
|
||||||
if( m_listview ) m_listview->SetMcdProvider( this );
|
if( m_listview ) m_listview->SetMcdProvider( this );
|
||||||
UpdateUI();
|
UpdateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =====================================================================================================
|
||||||
|
// MemoryCardListPanel_Simple (implementations)
|
||||||
|
// =====================================================================================================
|
||||||
|
|
||||||
void Panels::MemoryCardListPanel_Simple::UiCreateNewCard( McdSlotItem& card )
|
void Panels::MemoryCardListPanel_Simple::UiCreateNewCard( McdSlotItem& card )
|
||||||
{
|
{
|
||||||
if( card.IsPresent ){
|
if( card.IsPresent ){
|
||||||
|
@ -725,7 +683,6 @@ void Panels::MemoryCardListPanel_Simple::UiDeleteCard( McdSlotItem& card )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedCoreThreadClose closed_core;
|
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if( card.IsFormatted )
|
if( card.IsFormatted )
|
||||||
|
@ -733,26 +690,113 @@ void Panels::MemoryCardListPanel_Simple::UiDeleteCard( McdSlotItem& card )
|
||||||
wxString content;
|
wxString content;
|
||||||
content.Printf(
|
content.Printf(
|
||||||
pxE( "!Notice:Mcd:Delete",
|
pxE( "!Notice:Mcd:Delete",
|
||||||
L"You are about to delete the formatted memory card file '%s' [=slot %u]. "
|
L"You are about to delete the formatted memory card '%s'. "
|
||||||
L"All data on this card will be lost! Are you absolutely and quite positively sure?"
|
L"All data on this card will be lost! Are you absolutely and quite positively sure?"
|
||||||
), card.Filename.GetFullName().c_str()
|
), card.Filename.GetFullName().c_str()
|
||||||
, card.Slot
|
|
||||||
);
|
);
|
||||||
|
|
||||||
result = Msgbox::YesNo( content, _("Delete memory card file?") );
|
result = Msgbox::YesNo( content, _("Delete memory file?") );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( result )
|
if( result )
|
||||||
{
|
{
|
||||||
wxFileName fullpath( m_FolderPicker->GetPath() + card.Filename.GetFullName());//g_Conf->Mcd[GetSlotIndexForViewIndex( selectedViewIndex )].Filename.GetFullName() );
|
ScopedCoreThreadClose closed_core;
|
||||||
|
|
||||||
|
wxFileName fullpath( m_FolderPicker->GetPath() + card.Filename.GetFullName());
|
||||||
|
|
||||||
card.IsEnabled=false;
|
card.IsEnabled=false;
|
||||||
Apply();
|
Apply();
|
||||||
wxRemoveFile( fullpath.GetFullPath() );
|
wxRemoveFile( fullpath.GetFullPath() );
|
||||||
}
|
|
||||||
|
|
||||||
RefreshSelections();
|
RefreshSelections();
|
||||||
closed_core.AllowResume();
|
closed_core.AllowResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Panels::MemoryCardListPanel_Simple::UiDuplicateCard(McdSlotItem& src, McdSlotItem& dest)
|
||||||
|
{
|
||||||
|
wxDirName basepath = GetMcdPath();
|
||||||
|
if( !src.IsPresent )
|
||||||
|
{
|
||||||
|
Msgbox::Alert(_("Failed: Can only duplicate an existing card."), _("Duplicate memory card"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dest.IsPresent && dest.Slot!=-1 )
|
||||||
|
{
|
||||||
|
wxString content;
|
||||||
|
content.Printf(
|
||||||
|
pxE( "!Notice:Mcd:CantDuplicate",
|
||||||
|
L"Failed: Duplicate is only allowed to an empty PS2-Port or to the file system." )
|
||||||
|
);
|
||||||
|
|
||||||
|
Msgbox::Alert( content, _("Duplicate memory card") );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
wxString newFilename=L"";
|
||||||
|
newFilename = wxGetTextFromUser(_("Select a name for the duplicate\n( '.ps2' will be added automatically)"), _("Duplicate memory card"));
|
||||||
|
if( newFilename==L"" )
|
||||||
|
{
|
||||||
|
//Msgbox::Alert( _("Duplicate canceled"), _("Duplicate memory card") );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
newFilename += L".ps2";
|
||||||
|
|
||||||
|
//check that the name is valid for a new file
|
||||||
|
wxString errMsg;
|
||||||
|
if( !isValidNewFilename( newFilename, basepath, errMsg, 5 ) )
|
||||||
|
{
|
||||||
|
wxString message;
|
||||||
|
message.Printf(_("Failed: %s"), errMsg.c_str());
|
||||||
|
Msgbox::Alert( message, _("Duplicate memory card") );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest.Filename = newFilename;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxFileName srcfile( basepath + src.Filename);
|
||||||
|
wxFileName destfile( basepath + dest.Filename);
|
||||||
|
|
||||||
|
ScopedBusyCursor doh( Cursor_ReallyBusy );
|
||||||
|
ScopedCoreThreadClose closed_core;
|
||||||
|
|
||||||
|
if( !wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) )
|
||||||
|
{
|
||||||
|
wxString heading;
|
||||||
|
heading.Printf( pxE( "!Notice:Mcd:Copy Failed",
|
||||||
|
L"Failed: Destination memory card '%s' is in use." ),
|
||||||
|
dest.Filename.GetFullName().c_str(), dest.Slot
|
||||||
|
);
|
||||||
|
|
||||||
|
wxString content;
|
||||||
|
|
||||||
|
Msgbox::Alert( heading + L"\n\n" + content, _("Copy failed!") );
|
||||||
|
|
||||||
|
closed_core.AllowResume();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destination memcard isEnabled state is the same now as the source's
|
||||||
|
wxString success;
|
||||||
|
success.Printf(_("Memory card '%s' duplicated to '%s'.\n\nBoth card files are now identical."),
|
||||||
|
src.Filename.GetFullName().c_str(),
|
||||||
|
dest.Filename.GetFullName().c_str()
|
||||||
|
);
|
||||||
|
Msgbox::Alert(success, _("Success"));
|
||||||
|
dest.IsPresent=true;
|
||||||
|
dest.IsEnabled = true;
|
||||||
|
|
||||||
|
Apply();
|
||||||
|
DoRefresh();
|
||||||
|
closed_core.AllowResume();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::MemoryCardListPanel_Simple::UiRenameCard( McdSlotItem& card )
|
void Panels::MemoryCardListPanel_Simple::UiRenameCard( McdSlotItem& card )
|
||||||
|
@ -766,10 +810,10 @@ void Panels::MemoryCardListPanel_Simple::UiRenameCard( McdSlotItem& card )
|
||||||
wxString newFilename;
|
wxString newFilename;
|
||||||
while (1){
|
while (1){
|
||||||
wxString title;
|
wxString title;
|
||||||
title.Printf(_("Select a new name for the memory card file '%s'\n( '.ps2' will be added automatically)"),
|
title.Printf(_("Select a new name for the memory card '%s'\n( '.ps2' will be added automatically)"),
|
||||||
card.Filename.GetFullName().c_str()
|
card.Filename.GetFullName().c_str()
|
||||||
);
|
);
|
||||||
newFilename = wxGetTextFromUser(title, _("Rename memory card file"));
|
newFilename = wxGetTextFromUser(title, _("Rename memory card"));
|
||||||
if( newFilename==L"" )
|
if( newFilename==L"" )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -781,7 +825,7 @@ void Panels::MemoryCardListPanel_Simple::UiRenameCard( McdSlotItem& card )
|
||||||
{
|
{
|
||||||
wxString message;
|
wxString message;
|
||||||
message.Printf(_("Error (%s)"), errMsg.c_str());
|
message.Printf(_("Error (%s)"), errMsg.c_str());
|
||||||
Msgbox::Alert( message, _("Rename memory card file") );
|
Msgbox::Alert( message, _("Rename memory card") );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,7 +841,7 @@ void Panels::MemoryCardListPanel_Simple::UiRenameCard( McdSlotItem& card )
|
||||||
{
|
{
|
||||||
card.IsEnabled=origEnabled;
|
card.IsEnabled=origEnabled;
|
||||||
Apply();
|
Apply();
|
||||||
Msgbox::Alert( _("Error: Rename could not be completed.\n"), _("Rename memory card file") );
|
Msgbox::Alert( _("Error: Rename could not be completed.\n"), _("Rename memory card") );
|
||||||
|
|
||||||
closed_core.AllowResume();
|
closed_core.AllowResume();
|
||||||
return;
|
return;
|
||||||
|
@ -866,10 +910,79 @@ void Panels::MemoryCardListPanel_Simple::OnItemActivated(wxListEvent& evt)
|
||||||
|
|
||||||
if ( card.IsPresent )
|
if ( card.IsPresent )
|
||||||
UiRenameCard( card );
|
UiRenameCard( card );
|
||||||
else
|
else if (card.Slot>=0)
|
||||||
UiCreateNewCard( card );// IsPresent==false can only happen for an internal slot (vs filename on the HD), so a card can be created.
|
UiCreateNewCard( card );// IsPresent==false can only happen for an internal slot (vs filename on the HD), so a card can be created.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Panels::MemoryCardListPanel_Simple::OnDuplicateFile(wxCommandEvent& evt)
|
||||||
|
{
|
||||||
|
const int viewIndex = m_listview->GetFirstSelected();
|
||||||
|
if( wxNOT_FOUND == viewIndex ) return;
|
||||||
|
McdSlotItem& card( GetCardForViewIndex(viewIndex) );
|
||||||
|
|
||||||
|
pxAssert( card.IsPresent );
|
||||||
|
McdSlotItem dummy;
|
||||||
|
UiDuplicateCard(card, dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString GetPortName(int slotIndex)
|
||||||
|
{
|
||||||
|
if (slotIndex==0 || slotIndex==1)
|
||||||
|
return pxsFmt(wxString(L" ") + _("Port-%u / Multitap-%u--Port-1"), FileMcd_GetMtapPort(slotIndex)+1, FileMcd_GetMtapPort(slotIndex)+1);
|
||||||
|
return pxsFmt(wxString(L" ")+_(" Multitap-%u--Port-%u"), FileMcd_GetMtapPort(slotIndex)+1, FileMcd_GetMtapSlot(slotIndex)+1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panels::MemoryCardListPanel_Simple::UiAssignUnassignFile(McdSlotItem &card)
|
||||||
|
{
|
||||||
|
pxAssert( card.IsPresent );
|
||||||
|
|
||||||
|
if( card.Slot >=0 )
|
||||||
|
{//eject
|
||||||
|
card.IsEnabled = false;
|
||||||
|
card.IsPresent = false;
|
||||||
|
card.Filename = L"";
|
||||||
|
DoRefresh();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{//insert into a (UI) selected slot
|
||||||
|
wxArrayString selections;
|
||||||
|
int i;
|
||||||
|
for (i=0; i< GetNumVisibleInternalSlots(); i++)
|
||||||
|
{
|
||||||
|
McdSlotItem& selCard = GetCardForViewIndex(i);
|
||||||
|
wxString sel = GetPortName( selCard.Slot ) + L" ( ";
|
||||||
|
if (selCard.IsPresent)
|
||||||
|
sel += selCard.Filename.GetFullName();
|
||||||
|
else
|
||||||
|
sel += _("Empty");
|
||||||
|
sel += L" )";
|
||||||
|
|
||||||
|
selections.Add(sel);
|
||||||
|
}
|
||||||
|
wxString title;
|
||||||
|
title.Printf(_("Select a target port for '%s'"), card.Filename.GetFullName().c_str());
|
||||||
|
int res=wxGetSingleChoiceIndex(title, _("Insert card"), selections, this);
|
||||||
|
if( res<0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
McdSlotItem& target = GetCardForViewIndex(res);
|
||||||
|
bool en = target.IsPresent? target.IsEnabled : true;
|
||||||
|
RemoveCardFromSlot( card.Filename );
|
||||||
|
target.Filename = card.Filename;
|
||||||
|
target.IsPresent = true;
|
||||||
|
target.IsEnabled = en;
|
||||||
|
DoRefresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Panels::MemoryCardListPanel_Simple::OnAssignUnassignFile(wxCommandEvent& evt)
|
||||||
|
{
|
||||||
|
const int viewIndex = m_listview->GetFirstSelected();
|
||||||
|
if( wxNOT_FOUND == viewIndex ) return;
|
||||||
|
McdSlotItem& card( GetCardForViewIndex(viewIndex) );
|
||||||
|
|
||||||
|
UiAssignUnassignFile(card);
|
||||||
|
}
|
||||||
|
|
||||||
void Panels::MemoryCardListPanel_Simple::OnRenameFile(wxCommandEvent& evt)
|
void Panels::MemoryCardListPanel_Simple::OnRenameFile(wxCommandEvent& evt)
|
||||||
{
|
{
|
||||||
const int viewIndex = m_listview->GetFirstSelected();
|
const int viewIndex = m_listview->GetFirstSelected();
|
||||||
|
@ -908,14 +1021,22 @@ void Panels::MemoryCardListPanel_Simple::OnOpenItemContextMenu(wxListEvent& evt)
|
||||||
const McdSlotItem& card( GetCardForViewIndex(idx) );
|
const McdSlotItem& card( GetCardForViewIndex(idx) );
|
||||||
|
|
||||||
if (card.IsPresent){
|
if (card.IsPresent){
|
||||||
|
if (card.Slot>=0)
|
||||||
|
{
|
||||||
junk->Append( McdMenuId_Mount, card.IsEnabled ? _("Disable Port") : _("Enable Port") );
|
junk->Append( McdMenuId_Mount, card.IsEnabled ? _("Disable Port") : _("Enable Port") );
|
||||||
junk->Append( McdMenuId_Rename, _("Rename card file...") );
|
junk->AppendSeparator();
|
||||||
|
}
|
||||||
|
junk->Append( McdMenuId_AssignUnassign, card.Slot>=0?_("Eject card"):_("Insert card ...") );
|
||||||
|
junk->Append( McdMenuId_Duplicate, _("Duplicate card ...") );
|
||||||
|
junk->Append( McdMenuId_Rename, _("Rename card ...") );
|
||||||
}
|
}
|
||||||
|
|
||||||
junk->Append( McdMenuId_Create, card.IsPresent ? _("Delete card file") : _("Create a new card file...") );
|
if ( card.IsPresent || card.Slot>=0 )
|
||||||
|
{
|
||||||
|
junk->Append( McdMenuId_Create, card.IsPresent ? _("Delete card") : _("Create a new card ...") );
|
||||||
junk->AppendSeparator();
|
junk->AppendSeparator();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
junk->Append( McdMenuId_RefreshList, _("Refresh List") );
|
junk->Append( McdMenuId_RefreshList, _("Refresh List") );
|
||||||
|
|
||||||
|
@ -924,8 +1045,94 @@ void Panels::MemoryCardListPanel_Simple::OnOpenItemContextMenu(wxListEvent& evt)
|
||||||
UpdateUI();
|
UpdateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface Implementation for IMcdList
|
void Panels::MemoryCardListPanel_Simple::ReadFilesAtMcdFolder(){
|
||||||
int Panels::MemoryCardListPanel_Simple::GetLength() const
|
//Dir enumeration/iteration code courtesy of cotton. - avih.
|
||||||
|
while( m_allFilesystemCards.size() )
|
||||||
|
m_allFilesystemCards.pop_back();
|
||||||
|
|
||||||
|
m_filesystemPlaceholderCard.Slot=-1;
|
||||||
|
m_filesystemPlaceholderCard.IsEnabled=false;
|
||||||
|
m_filesystemPlaceholderCard.IsPresent=false;
|
||||||
|
m_filesystemPlaceholderCard.Filename=L"";
|
||||||
|
|
||||||
|
|
||||||
|
wxArrayString memcardList;
|
||||||
|
wxDir::GetAllFiles(m_FolderPicker->GetPath().ToString(), &memcardList, L"*.ps2", wxDIR_FILES);
|
||||||
|
|
||||||
|
for(uint i = 0; i < memcardList.size(); i++) {
|
||||||
|
McdSlotItem currentCardFile;
|
||||||
|
bool isOk=EnumerateMemoryCard( currentCardFile, memcardList[i], m_FolderPicker->GetPath() );
|
||||||
|
if( isOk && !isFileAssignedAndVisibleOnList( currentCardFile.Filename ) )
|
||||||
|
{
|
||||||
|
currentCardFile.Slot = -1;
|
||||||
|
currentCardFile.IsEnabled = false;
|
||||||
|
m_allFilesystemCards.push_back(currentCardFile);
|
||||||
|
DevCon.WriteLn(L"Enumerated file: '%s'", currentCardFile.Filename.GetFullName().c_str() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DevCon.WriteLn(L"MCD folder card file skipped: '%s'", memcardList[i].c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Panels::MemoryCardListPanel_Simple::IsSlotVisible(int slotIndex) const
|
||||||
|
{
|
||||||
|
if ( slotIndex<0 || slotIndex>=8 ) return false;
|
||||||
|
if ( !m_MultitapEnabled[0] && 2<=slotIndex && slotIndex<=4) return false;
|
||||||
|
if ( !m_MultitapEnabled[1] && 5<=slotIndex && slotIndex<=7) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//whether or not this filename appears on the ports at the list (takes into account MT enabled/disabled)
|
||||||
|
bool Panels::MemoryCardListPanel_Simple::isFileAssignedAndVisibleOnList(const wxFileName cardFile) const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for( i=0; i<8; i++)
|
||||||
|
if ( IsSlotVisible(i) && cardFile.GetFullName()==m_Cards[i].Filename.GetFullName() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//whether or not this filename is assigned to a ports (regardless if MT enabled/disabled)
|
||||||
|
bool Panels::MemoryCardListPanel_Simple::isFileAssignedToInternalSlot(const wxFileName cardFile) const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for( i=0; i<8; i++)
|
||||||
|
if ( cardFile.GetFullName()==m_Cards[i].Filename.GetFullName() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panels::MemoryCardListPanel_Simple::RemoveCardFromSlot(const wxFileName cardFile)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for( i=0; i<8; i++)
|
||||||
|
if ( cardFile.GetFullName()==m_Cards[i].Filename.GetFullName() )
|
||||||
|
{
|
||||||
|
m_Cards[i].Filename = L"";
|
||||||
|
m_Cards[i].IsPresent = false;
|
||||||
|
m_Cards[i].IsEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Panels::MemoryCardListPanel_Simple::GetNumFilesVisibleAsFilesystem() const
|
||||||
|
{
|
||||||
|
return m_allFilesystemCards.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Panels::MemoryCardListPanel_Simple::IsNonEmptyFilesystemCards() const
|
||||||
|
{
|
||||||
|
return GetNumFilesVisibleAsFilesystem()>0;
|
||||||
|
}
|
||||||
|
|
||||||
|
McdSlotItem& Panels::MemoryCardListPanel_Simple::GetNthVisibleFilesystemCard(int n)
|
||||||
|
{
|
||||||
|
return m_allFilesystemCards.at(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Panels::MemoryCardListPanel_Simple::GetNumVisibleInternalSlots() const
|
||||||
{
|
{
|
||||||
uint baselen = 2;
|
uint baselen = 2;
|
||||||
if( m_MultitapEnabled[0] ) baselen += 3;
|
if( m_MultitapEnabled[0] ) baselen += 3;
|
||||||
|
@ -933,8 +1140,17 @@ int Panels::MemoryCardListPanel_Simple::GetLength() const
|
||||||
return baselen;
|
return baselen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interface Implementation for IMcdList
|
||||||
|
int Panels::MemoryCardListPanel_Simple::GetLength() const
|
||||||
|
{
|
||||||
|
uint baselen = GetNumVisibleInternalSlots();
|
||||||
|
baselen++;//filesystem placeholder
|
||||||
|
baselen+= GetNumFilesVisibleAsFilesystem();
|
||||||
|
return baselen;
|
||||||
|
}
|
||||||
|
|
||||||
//Translates a list-view index (idx) to a memory card slot.
|
|
||||||
|
//Translates a list-view index (idx) to an internal memory card slot.
|
||||||
//This method effectively defines the arrangement of the card slots at the list view.
|
//This method effectively defines the arrangement of the card slots at the list view.
|
||||||
//The internal card slots array is fixed as sollows:
|
//The internal card slots array is fixed as sollows:
|
||||||
// slot 0: mcd1 (= MT1 slot 1)
|
// slot 0: mcd1 (= MT1 slot 1)
|
||||||
|
@ -948,6 +1164,7 @@ int Panels::MemoryCardListPanel_Simple::GetLength() const
|
||||||
// using any other set of 'view-index-to-card-slot' translating that we'd like.
|
// using any other set of 'view-index-to-card-slot' translating that we'd like.
|
||||||
int Panels::MemoryCardListPanel_Simple::GetSlotIndexForViewIndex( int listViewIndex )
|
int Panels::MemoryCardListPanel_Simple::GetSlotIndexForViewIndex( int listViewIndex )
|
||||||
{
|
{
|
||||||
|
pxAssert( 0<=listViewIndex && listViewIndex<GetNumVisibleInternalSlots() );
|
||||||
int targetSlot=-1;
|
int targetSlot=-1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -989,13 +1206,20 @@ int Panels::MemoryCardListPanel_Simple::GetSlotIndexForViewIndex( int listViewIn
|
||||||
targetSlot=listViewIndex;
|
targetSlot=listViewIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(targetSlot>=0);
|
pxAssert( 0<=targetSlot && targetSlot<=7 );
|
||||||
return targetSlot;
|
return targetSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
McdSlotItem& Panels::MemoryCardListPanel_Simple::GetCardForViewIndex( int idx )
|
McdSlotItem& Panels::MemoryCardListPanel_Simple::GetCardForViewIndex( int idx )
|
||||||
{
|
{
|
||||||
int slot = GetSlotIndexForViewIndex( idx );
|
pxAssert( 0<=idx && idx< GetNumVisibleInternalSlots()+1+GetNumFilesVisibleAsFilesystem() );
|
||||||
return m_Cards[slot];
|
|
||||||
|
if( 0<=idx && idx<GetNumVisibleInternalSlots() )
|
||||||
|
return m_Cards[GetSlotIndexForViewIndex( idx )];
|
||||||
|
|
||||||
|
if( idx == GetNumVisibleInternalSlots() )
|
||||||
|
return this->m_filesystemPlaceholderCard;
|
||||||
|
|
||||||
|
return this->m_allFilesystemCards.at( idx - GetNumVisibleInternalSlots() - 1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,13 +102,13 @@ const ListViewColumnInfo& MemoryCardListView_Simple::GetDefaultColumnInfo( uint
|
||||||
{
|
{
|
||||||
static const ListViewColumnInfo columns[] =
|
static const ListViewColumnInfo columns[] =
|
||||||
{
|
{
|
||||||
{ _("PS2 Port") , 160 , wxLIST_FORMAT_LEFT },
|
{ _("PS2 Port") , 154 , wxLIST_FORMAT_LEFT },
|
||||||
{ _("Port status") , 80 , wxLIST_FORMAT_LEFT },
|
{ _("Port status") , 80 , wxLIST_FORMAT_LEFT },
|
||||||
{ _("File name") , 128 , wxLIST_FORMAT_LEFT },
|
{ _("File name") , 126 , wxLIST_FORMAT_LEFT },
|
||||||
{ _("File size") , 80 , wxLIST_FORMAT_LEFT },
|
{ _("File size") , 60 , wxLIST_FORMAT_LEFT },
|
||||||
{ _("Formatted") , 80 , wxLIST_FORMAT_LEFT },
|
{ _("Formatted") , 80 , wxLIST_FORMAT_LEFT },
|
||||||
{ _("Last Modified"), 96 , wxLIST_FORMAT_LEFT },
|
{ _("Last Modified"), 85 , wxLIST_FORMAT_LEFT },
|
||||||
{ _("Created on") , 96 , wxLIST_FORMAT_LEFT },
|
{ _("Created on") , 85 , wxLIST_FORMAT_LEFT },
|
||||||
};
|
};
|
||||||
|
|
||||||
pxAssumeDev( idx < ArraySize(columns), "ListView column index is out of bounds." );
|
pxAssumeDev( idx < ArraySize(columns), "ListView column index is out of bounds." );
|
||||||
|
@ -133,15 +133,22 @@ wxString MemoryCardListView_Simple::OnGetItemText(long item, long column) const
|
||||||
switch( column )
|
switch( column )
|
||||||
{
|
{
|
||||||
case McdColS_PortSlot:
|
case McdColS_PortSlot:
|
||||||
if (!it.IsMultitapSlot())
|
if (it.Slot>=0)
|
||||||
|
{
|
||||||
|
if( !it.IsMultitapSlot() )
|
||||||
return pxsFmt(wxString(L" ") + _("Port-%u / Multitap-%u--Port-1"), it.GetMtapPort()+1, it.GetMtapPort()+1);
|
return pxsFmt(wxString(L" ") + _("Port-%u / Multitap-%u--Port-1"), it.GetMtapPort()+1, it.GetMtapPort()+1);
|
||||||
return pxsFmt(wxString(L" ") + _("Multitap-%u--Port-%u"), it.GetMtapPort()+1, it.GetMtapSlot()+1);
|
return pxsFmt(wxString(L" ")+_(" Multitap-%u--Port-%u"), it.GetMtapPort()+1, it.GetMtapSlot()+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return L"";
|
||||||
|
|
||||||
case McdColS_Status:
|
case McdColS_Status:
|
||||||
{
|
{
|
||||||
wxString res = prefix + (it.IsEnabled ? _("Enabled") : _("Disabled"));
|
wxString res = prefix + (it.IsEnabled ? _("Enabled") : _("Disabled"));
|
||||||
if( !it.IsPresent )
|
if( !it.IsPresent && it.Slot>=0 )
|
||||||
res = prefix + _("Empty");
|
res = prefix + _("Empty");
|
||||||
|
else if ( it.Slot == -1 )
|
||||||
|
res= L"";
|
||||||
return prefix + res;
|
return prefix + res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +159,17 @@ wxString MemoryCardListView_Simple::OnGetItemText(long item, long column) const
|
||||||
|
|
||||||
case McdColS_Filename:
|
case McdColS_Filename:
|
||||||
{
|
{
|
||||||
if (!it.IsPresent) return L"";
|
if (!it.IsPresent && it.Slot!=-1) return L"";
|
||||||
|
else if (!it.IsPresent && it.Slot==-1)
|
||||||
|
{
|
||||||
|
//UGLY #2: because this method must be const to be used at the list,
|
||||||
|
// it cannot access GetMcdProvider() which isn't (and shouldn't be) const.
|
||||||
|
//so.. a plain old cast does the trick. Hope it's not too bad. - avih.
|
||||||
|
if (((MemoryCardListView_Simple*)this)->GetMcdProvider().IsNonEmptyFilesystemCards())
|
||||||
|
return _("[-- Unused cards --]");
|
||||||
|
else
|
||||||
|
return _("[-- No unused cards --]");
|
||||||
|
}
|
||||||
|
|
||||||
wxDirName filepath( it.Filename.GetPath() );
|
wxDirName filepath( it.Filename.GetPath() );
|
||||||
|
|
||||||
|
@ -194,7 +211,7 @@ wxListItemAttr* MemoryCardListView_Simple::OnGetItemAttr(long item) const
|
||||||
|
|
||||||
m_ItemAttr = wxListItemAttr(); // Wipe it clean!
|
m_ItemAttr = wxListItemAttr(); // Wipe it clean!
|
||||||
|
|
||||||
if( it.IsPresent && !it.IsEnabled)
|
if( it.Slot==-1 || it.IsPresent && !it.IsEnabled)
|
||||||
m_ItemAttr.SetTextColour( *wxLIGHT_GREY );
|
m_ItemAttr.SetTextColour( *wxLIGHT_GREY );
|
||||||
/*
|
/*
|
||||||
if( m_TargetedItem == item )
|
if( m_TargetedItem == item )
|
||||||
|
|
|
@ -79,6 +79,11 @@ public:
|
||||||
virtual int GetSlotIndexForViewIndex( int listViewIndex )=0;
|
virtual int GetSlotIndexForViewIndex( int listViewIndex )=0;
|
||||||
virtual wxDirName GetMcdPath() const=0;
|
virtual wxDirName GetMcdPath() const=0;
|
||||||
virtual void PublicApply() =0;
|
virtual void PublicApply() =0;
|
||||||
|
virtual bool isFileAssignedToInternalSlot(const wxFileName cardFile) const =0;
|
||||||
|
virtual void RemoveCardFromSlot(const wxFileName cardFile) =0;
|
||||||
|
virtual bool IsNonEmptyFilesystemCards() const =0;
|
||||||
|
virtual bool UiDuplicateCard( McdSlotItem& src, McdSlotItem& dest ) =0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -95,10 +100,17 @@ protected:
|
||||||
int m_TargetedItem;
|
int m_TargetedItem;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void (*m_externHandler)(void);
|
||||||
|
void setExternHandler(void (*f)(void)){m_externHandler=f;};
|
||||||
|
void OnChanged(wxEvent& evt){if (m_externHandler) m_externHandler(); evt.Skip();}
|
||||||
|
|
||||||
virtual ~BaseMcdListView() throw() { }
|
virtual ~BaseMcdListView() throw() { }
|
||||||
BaseMcdListView( wxWindow* parent )
|
BaseMcdListView( wxWindow* parent )
|
||||||
: _parent( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_VIRTUAL )
|
: _parent( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_VIRTUAL )
|
||||||
{
|
{
|
||||||
|
m_externHandler=NULL;
|
||||||
|
Connect( this->GetId(), wxEVT_LEFT_UP, wxEventHandler(BaseMcdListView::OnChanged));
|
||||||
|
|
||||||
m_CardProvider = NULL;
|
m_CardProvider = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,11 +210,15 @@ namespace Panels
|
||||||
// Doubles as Create and Delete buttons
|
// Doubles as Create and Delete buttons
|
||||||
wxButton* m_button_Create;
|
wxButton* m_button_Create;
|
||||||
|
|
||||||
// Doubles as Mount and Unmount buttons
|
// Doubles as Mount and Unmount buttons ("Enable"/"Disable" port)
|
||||||
wxButton* m_button_Mount;
|
wxButton* m_button_Mount;
|
||||||
|
|
||||||
|
wxButton* m_button_AssignUnassign; //insert/eject card
|
||||||
|
wxButton* m_button_Duplicate;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~MemoryCardListPanel_Simple() throw() {}
|
virtual ~MemoryCardListPanel_Simple() throw();
|
||||||
MemoryCardListPanel_Simple( wxWindow* parent );
|
MemoryCardListPanel_Simple( wxWindow* parent );
|
||||||
|
|
||||||
void UpdateUI();
|
void UpdateUI();
|
||||||
|
@ -213,12 +229,16 @@ namespace Panels
|
||||||
virtual McdSlotItem& GetCardForViewIndex( int idx );
|
virtual McdSlotItem& GetCardForViewIndex( int idx );
|
||||||
virtual int GetSlotIndexForViewIndex( int viewIndex );
|
virtual int GetSlotIndexForViewIndex( int viewIndex );
|
||||||
virtual void PublicApply(){ Apply(); };
|
virtual void PublicApply(){ Apply(); };
|
||||||
|
void OnChangedListSelection(){ UpdateUI(); };
|
||||||
|
virtual bool UiDuplicateCard( McdSlotItem& src, McdSlotItem& dest );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void OnCreateOrDeleteCard(wxCommandEvent& evt);
|
void OnCreateOrDeleteCard(wxCommandEvent& evt);
|
||||||
void OnMountCard(wxCommandEvent& evt);
|
void OnMountCard(wxCommandEvent& evt);
|
||||||
// void OnRelocateCard(wxCommandEvent& evt);
|
// void OnRelocateCard(wxCommandEvent& evt);
|
||||||
void OnRenameFile(wxCommandEvent& evt);
|
void OnRenameFile(wxCommandEvent& evt);
|
||||||
|
void OnDuplicateFile(wxCommandEvent& evt);
|
||||||
|
void OnAssignUnassignFile(wxCommandEvent& evt);
|
||||||
|
|
||||||
void OnListDrag(wxListEvent& evt);
|
void OnListDrag(wxListEvent& evt);
|
||||||
void OnListSelectionChanged(wxListEvent& evt);
|
void OnListSelectionChanged(wxListEvent& evt);
|
||||||
|
@ -227,6 +247,19 @@ namespace Panels
|
||||||
|
|
||||||
virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames);
|
virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames);
|
||||||
|
|
||||||
|
std::vector<McdSlotItem> m_allFilesystemCards;
|
||||||
|
McdSlotItem m_filesystemPlaceholderCard;
|
||||||
|
|
||||||
|
virtual int GetNumFilesVisibleAsFilesystem() const;
|
||||||
|
virtual int GetNumVisibleInternalSlots() const;
|
||||||
|
virtual McdSlotItem& GetNthVisibleFilesystemCard(int n);
|
||||||
|
virtual bool IsSlotVisible(int slotIndex) const;
|
||||||
|
virtual void ReadFilesAtMcdFolder();
|
||||||
|
virtual bool isFileAssignedAndVisibleOnList(const wxFileName cardFile) const;
|
||||||
|
virtual bool isFileAssignedToInternalSlot(const wxFileName cardFile) const;
|
||||||
|
virtual void RemoveCardFromSlot(const wxFileName cardFile);
|
||||||
|
virtual bool IsNonEmptyFilesystemCards() const;
|
||||||
|
|
||||||
virtual void Apply();
|
virtual void Apply();
|
||||||
virtual void AppStatusEvent_OnSettingsApplied();
|
virtual void AppStatusEvent_OnSettingsApplied();
|
||||||
virtual void DoRefresh();
|
virtual void DoRefresh();
|
||||||
|
@ -235,6 +268,8 @@ namespace Panels
|
||||||
virtual void UiRenameCard( McdSlotItem& card );
|
virtual void UiRenameCard( McdSlotItem& card );
|
||||||
virtual void UiCreateNewCard( McdSlotItem& card );
|
virtual void UiCreateNewCard( McdSlotItem& card );
|
||||||
virtual void UiDeleteCard( McdSlotItem& card );
|
virtual void UiDeleteCard( McdSlotItem& card );
|
||||||
|
virtual void UiAssignUnassignFile( McdSlotItem& card );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue