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:
avihal@gmail.com 2011-03-17 18:41:59 +00:00
parent c704b89cd1
commit 269f030778
7 changed files with 449 additions and 173 deletions

View File

@ -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.
} }
} }

View File

@ -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;
} }

View File

@ -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;

View File

@ -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 )
); );
} }

View File

@ -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,116 +369,44 @@ 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;
src.Filename = tmpFilename; if (dest.Slot>=0)
src.IsPresent = tmpPresent; {//2 internal slots: swap
src.Filename = tmpFilename;
src.IsPresent = tmpPresent;
}
else
{//dest is at the filesystem (= remove card from slot)
src.Filename = L"";
src.IsPresent = false;
src.IsEnabled = false;
}
} }
} }
@ -485,24 +414,23 @@ public:
} }
}; };
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();
closed_core.AllowResume();
} }
RefreshSelections(); }
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,13 +1021,21 @@ void Panels::MemoryCardListPanel_Simple::OnOpenItemContextMenu(wxListEvent& evt)
const McdSlotItem& card( GetCardForViewIndex(idx) ); const McdSlotItem& card( GetCardForViewIndex(idx) );
if (card.IsPresent){ if (card.IsPresent){
junk->Append( McdMenuId_Mount, card.IsEnabled ? _("Disable Port") : _("Enable Port") ); if (card.Slot>=0)
junk->Append( McdMenuId_Rename, _("Rename card file...") ); {
junk->Append( McdMenuId_Mount, card.IsEnabled ? _("Disable Port") : _("Enable Port") );
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->AppendSeparator(); junk->Append( McdMenuId_Create, card.IsPresent ? _("Delete card") : _("Create a new card ...") );
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 );
} }

View File

@ -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." );
@ -128,20 +128,27 @@ wxString MemoryCardListView_Simple::OnGetItemText(long item, long column) const
{ {
if( !m_CardProvider ) return _parent::OnGetItemText(item, column); if( !m_CardProvider ) return _parent::OnGetItemText(item, column);
const McdSlotItem& it( m_CardProvider->GetCardForViewIndex(item) ); const McdSlotItem& it( m_CardProvider->GetCardForViewIndex(item) );
wxString prefix=L" "; wxString prefix=L" ";
switch( column ) switch( column )
{ {
case McdColS_PortSlot: case McdColS_PortSlot:
if (!it.IsMultitapSlot()) if (it.Slot>=0)
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); if( !it.IsMultitapSlot() )
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 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 )

View File

@ -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 );
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------