/[pcsx2_0.9.7]/trunk/pcsx2/gui/Panels/MemoryCardListPanel.cpp
ViewVC logotype

Contents of /trunk/pcsx2/gui/Panels/MemoryCardListPanel.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 2 months ago) by william
File size: 20676 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #include "PrecompiledHeader.h"
17 #include "AppCoreThread.h"
18 #include "System.h"
19 #include "MemoryCardFile.h"
20
21 #include "ConfigurationPanels.h"
22 #include "MemoryCardPanels.h"
23
24 #include "Dialogs/ConfigurationDialog.h"
25 #include "Utilities/IniInterface.h"
26
27 #include <wx/filepicker.h>
28 #include <wx/ffile.h>
29 #include <wx/dir.h>
30
31
32 using namespace pxSizerFlags;
33 using namespace Panels;
34
35 static bool IsMcdFormatted( wxFFile& fhand )
36 {
37 static const char formatted_string[] = "Sony PS2 Memory Card Format";
38 static const int fmtstrlen = sizeof( formatted_string )-1;
39
40 char dest[fmtstrlen];
41
42 fhand.Read( dest, fmtstrlen );
43 return memcmp( formatted_string, dest, fmtstrlen ) == 0;
44 }
45
46 bool EnumerateMemoryCard( McdListItem& dest, const wxFileName& filename )
47 {
48 dest.IsFormatted = false;
49 dest.IsPresent = false;
50
51 const wxString fullpath( filename.GetFullPath() );
52 if( !filename.FileExists() ) return false;
53
54 Console.WriteLn( fullpath );
55 wxFFile mcdFile( fullpath );
56 if( !mcdFile.IsOpened() ) return false; // wx should log the error for us.
57 if( mcdFile.Length() < (1024*528) )
58 {
59 Console.Warning( "... MemoryCard appears to be truncated. Ignoring." );
60 return false;
61 }
62
63 dest.IsPresent = true;
64 dest.Filename = filename;
65 dest.SizeInMB = (uint)(mcdFile.Length() / (1024 * 528 * 2));
66 dest.IsFormatted = IsMcdFormatted( mcdFile );
67 filename.GetTimes( NULL, &dest.DateModified, &dest.DateCreated );
68
69 return true;
70 }
71
72 static int EnumerateMemoryCards( McdList& dest, const wxArrayString& files )
73 {
74 int pushed = 0;
75 Console.WriteLn( Color_StrongBlue, "Enumerating memory cards..." );
76 for( size_t i=0; i<files.GetCount(); ++i )
77 {
78 ConsoleIndentScope con_indent;
79 McdListItem mcdItem;
80 if( EnumerateMemoryCard(mcdItem, files[i]) )
81 {
82 dest.push_back( mcdItem );
83 ++pushed;
84 }
85 }
86 if( pushed > 0 )
87 Console.WriteLn( Color_StrongBlue, "Memory card Enumeration Complete." );
88 else
89 Console.WriteLn( Color_StrongBlue, "No valid memory card found." );
90
91 return pushed;
92 }
93
94 // --------------------------------------------------------------------------------------
95 // McdListItem (implementations)
96 // --------------------------------------------------------------------------------------
97 bool McdListItem::IsMultitapSlot() const
98 {
99 return FileMcd_IsMultitapSlot(Slot);
100 }
101
102 uint McdListItem::GetMtapPort() const
103 {
104 return FileMcd_GetMtapPort(Slot);
105 }
106
107 uint McdListItem::GetMtapSlot() const
108 {
109 return FileMcd_GetMtapSlot(Slot);
110 }
111
112 // Compares two cards -- If this equality comparison is used on items where
113 // no filename is specified, then the check will include port and slot.
114 bool McdListItem::operator==( const McdListItem& right ) const
115 {
116 bool fileEqu;
117
118 if( Filename.GetFullName().IsEmpty() )
119 fileEqu = OpEqu(Slot);
120 else
121 fileEqu = OpEqu(Filename);
122
123 return fileEqu &&
124 OpEqu(IsPresent) && OpEqu(IsEnabled) &&
125 OpEqu(SizeInMB) && OpEqu(IsFormatted) &&
126 OpEqu(DateCreated) && OpEqu(DateModified);
127 }
128
129 bool McdListItem::operator!=( const McdListItem& right ) const
130 {
131 return operator==( right );
132 }
133
134 //DEFINE_EVENT_TYPE( pxEvt_RefreshSelections );
135
136 // =====================================================================================================
137 // BaseMcdListPanel (implementations)
138 // =====================================================================================================
139 Panels::BaseMcdListPanel::BaseMcdListPanel( wxWindow* parent )
140 : _parent( parent )
141 {
142 m_FolderPicker = new DirPickerPanel( this, FolderId_MemoryCards,
143 //_("memory card Search Path:"), // static box label
144 _("Select folder with PS2 memory cards") // dir picker popup label
145 );
146
147 m_listview = NULL;
148
149 m_btn_Refresh = new wxButton( this, wxID_ANY, _("Refresh list") );
150
151 Connect( m_btn_Refresh->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BaseMcdListPanel::OnRefreshSelections) );
152 //Connect( pxEvt_RefreshSelections, wxCommandEventHandler(BaseMcdListPanel::OnRefreshSelections) );
153 }
154
155 void Panels::BaseMcdListPanel::RefreshMcds() const
156 {
157 wxCommandEvent refit( wxEVT_COMMAND_BUTTON_CLICKED );
158 refit.SetId( m_btn_Refresh->GetId() );
159 GetEventHandler()->AddPendingEvent( refit );
160 }
161
162 void Panels::BaseMcdListPanel::CreateLayout()
163 {
164 //if( m_listview ) m_listview->SetMinSize( wxSize( 480, 140 ) );
165
166 wxBoxSizer& s_buttons(*new wxBoxSizer( wxHORIZONTAL ));
167 s_leftside_buttons = new wxBoxSizer( wxHORIZONTAL );
168 s_rightside_buttons = new wxBoxSizer( wxHORIZONTAL );
169
170 s_buttons += s_leftside_buttons | pxAlignLeft;
171 s_buttons += pxStretchSpacer();
172 s_buttons += s_rightside_buttons | pxAlignRight;
173
174 if( m_FolderPicker ) *this += m_FolderPicker | pxExpand;
175 if( m_listview ) *this += m_listview | pxExpand;
176 *this += s_buttons | pxExpand;
177
178 *s_leftside_buttons += m_btn_Refresh;
179
180 if (m_listview)
181 {
182 IniLoader loader;
183 ScopedIniGroup group( loader, L"MemoryCardListPanel" );
184 m_listview->LoadSaveColumns( loader );
185 }
186 }
187
188 void Panels::BaseMcdListPanel::Apply()
189 {
190 // Save column widths to the configuration file. Since these are used *only* by this
191 // dialog, we use a direct local ini save approach, instead of going through g_conf.
192 uint colcnt = m_listview->GetColumnCount();
193
194 if (m_listview)
195 {
196 IniSaver saver;
197 ScopedIniGroup group( saver, L"MemoryCardListPanel" );
198 m_listview->LoadSaveColumns(saver);
199 }
200 }
201
202 void Panels::BaseMcdListPanel::AppStatusEvent_OnSettingsApplied()
203 {
204 if( (m_MultitapEnabled[0] != g_Conf->EmuOptions.MultitapPort0_Enabled) ||
205 (m_MultitapEnabled[0] != g_Conf->EmuOptions.MultitapPort0_Enabled) )
206 {
207 m_MultitapEnabled[0] = g_Conf->EmuOptions.MultitapPort0_Enabled;
208 m_MultitapEnabled[1] = g_Conf->EmuOptions.MultitapPort1_Enabled;
209
210 RefreshMcds();
211 }
212 }
213
214 // --------------------------------------------------------------------------------------
215 // McdDataObject
216 // --------------------------------------------------------------------------------------
217 class WXDLLEXPORT McdDataObject : public wxDataObjectSimple
218 {
219 DECLARE_NO_COPY_CLASS(McdDataObject)
220
221 protected:
222 int m_slot;
223
224 public:
225 McdDataObject(int slot = -1)
226 : wxDataObjectSimple( wxDF_PRIVATE )
227 {
228 m_slot = slot;
229 }
230
231 uint GetSlot() const
232 {
233 pxAssumeDev( m_slot >= 0, "memory card Index is uninitialized (invalid drag&drop object state)" );
234 return (uint)m_slot;
235 }
236
237 size_t GetDataSize() const
238 {
239 return sizeof(u32);
240 }
241
242 bool GetDataHere(void *buf) const
243 {
244 *(u32*)buf = GetSlot();
245 return true;
246 }
247
248 virtual bool SetData(size_t len, const void *buf)
249 {
250 if( !pxAssertDev( len == sizeof(u32), "Data length mismatch on memory card drag&drop operation." ) ) return false;
251
252 m_slot = *(u32*)buf;
253 return ( (uint)m_slot < 8 ); // sanity check (unsigned, so that -1 also is invalid) :)
254 }
255
256 // Must provide overloads to avoid hiding them (and warnings about it)
257 virtual size_t GetDataSize(const wxDataFormat&) const
258 {
259 return GetDataSize();
260 }
261
262 virtual bool GetDataHere(const wxDataFormat&, void *buf) const
263 {
264 return GetDataHere(buf);
265 }
266
267 virtual bool SetData(const wxDataFormat&, size_t len, const void *buf)
268 {
269 return SetData(len, buf);
270 }
271 };
272
273 class McdDropTarget : public wxDropTarget
274 {
275 protected:
276 BaseMcdListView* m_listview;
277
278 public:
279 McdDropTarget( BaseMcdListView* listview=NULL )
280 {
281 m_listview = listview;
282 SetDataObject(new McdDataObject());
283 }
284
285 // these functions are called when data is moved over position (x, y) and
286 // may return either wxDragCopy, wxDragMove or wxDragNone depending on
287 // what would happen if the data were dropped here.
288 //
289 // the last parameter is what would happen by default and is determined by
290 // the platform-specific logic (for example, under Windows it's wxDragCopy
291 // if Ctrl key is pressed and wxDragMove otherwise) except that it will
292 // always be wxDragNone if the carried data is in an unsupported format.
293
294
295 // called when the mouse moves in the window - shouldn't take long to
296 // execute or otherwise mouse movement would be too slow.
297 virtual wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
298 {
299 int flags = 0;
300 int idx = m_listview->HitTest( wxPoint(x,y), flags);
301 m_listview->SetTargetedItem( idx );
302
303 if( wxNOT_FOUND == idx ) return wxDragNone;
304
305 return def;
306 }
307
308 virtual void OnLeave()
309 {
310 m_listview->SetTargetedItem( wxNOT_FOUND );
311 }
312
313 // this function is called when data is dropped at position (x, y) - if it
314 // returns true, OnData() will be called immediately afterwards which will
315 // allow to retrieve the data dropped.
316 virtual bool OnDrop(wxCoord x, wxCoord y)
317 {
318 int flags = 0;
319 int idx = m_listview->HitTest( wxPoint(x,y), flags);
320 return ( wxNOT_FOUND != idx );
321 }
322
323 // may be called *only* from inside OnData() and will fill m_dataObject
324 // with the data from the drop source if it returns true
325 virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def)
326 {
327 m_listview->SetTargetedItem( wxNOT_FOUND );
328
329 int flags = 0;
330 int idx = m_listview->HitTest( wxPoint(x,y), flags);
331 if( wxNOT_FOUND == idx ) return wxDragNone;
332
333 if ( !GetData() ) return wxDragNone;
334
335 McdDataObject *dobj = (McdDataObject *)m_dataObject;
336
337 wxDragResult result = OnDropMcd(
338 m_listview->GetMcdProvider().GetCard(dobj->GetSlot()),
339 m_listview->GetMcdProvider().GetCard(idx),
340 def
341 );
342
343 if( wxDragNone == result ) return wxDragNone;
344 m_listview->GetMcdProvider().RefreshMcds();
345
346 return result;
347 }
348
349 virtual wxDragResult OnDropMcd( const McdListItem& src, const McdListItem& dest, wxDragResult def )
350 {
351 if( src.Slot == dest.Slot ) return wxDragNone;
352 if( !pxAssert( (src.Slot >= 0) && (dest.Slot >= 0) ) ) return wxDragNone;
353
354 const wxDirName basepath( m_listview->GetMcdProvider().GetMcdPath() );
355 wxFileName srcfile( basepath + g_Conf->Mcd[src.Slot].Filename );
356 wxFileName destfile( basepath + g_Conf->Mcd[dest.Slot].Filename );
357
358 if( wxDragCopy == def )
359 {
360 // user is force invoking copy mode, which means we need to check the destination
361 // and prompt if it looks valuable (formatted).
362
363 if( dest.IsPresent && dest.IsFormatted )
364 {
365 pxsFmt( pxE( "!Notice:Mcd:Overwrite",
366 L"This will copy the contents of the memory card in slot %u over the memory card in slot %u. "
367 L"All data on the target slot will be lost. Are you sure?" ),
368 src.Slot, dest.Slot
369 );
370
371 //if( !Msgbox::OkCancel( ) )
372 // return wxDragNone;
373 }
374
375 ScopedBusyCursor doh( Cursor_ReallyBusy );
376 if( !wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) )
377 {
378 wxString heading;
379 heading.Printf( pxE( "!Notice:Mcd:Copy Failed",
380 L"Error! Could not copy the memory card into slot %u. The destination file is in use." ),
381 dest.Slot
382 );
383
384 wxString content;
385
386 Msgbox::Alert( heading + L"\n\n" + content, _("Copy failed!") );
387 return wxDragNone;
388 }
389 }
390 else if( wxDragMove == def )
391 {
392 // Move always performs a swap :)
393
394 const bool srcExists( srcfile.FileExists() );
395 const bool destExists( destfile.FileExists() );
396
397 bool result = true;
398
399 if( destExists && srcExists)
400 {
401 wxFileName tempname;
402 tempname.AssignTempFileName( basepath.ToString() );
403
404 // Neat trick to handle errors.
405 result = result && wxRenameFile( srcfile.GetFullPath(), tempname.GetFullPath(), true );
406 result = result && wxRenameFile( destfile.GetFullPath(), srcfile.GetFullPath(), false );
407 result = result && wxRenameFile( tempname.GetFullPath(), destfile.GetFullPath(), true );
408 }
409 else if( destExists )
410 {
411 result = wxRenameFile( destfile.GetFullPath(), srcfile.GetFullPath() );
412 }
413 else if( srcExists )
414 {
415 result = wxRenameFile( srcfile.GetFullPath(), destfile.GetFullPath() );
416 }
417
418 if( !result )
419 {
420 // TODO : Popup an error to the user.
421
422 Console.Error( "(FileMcd) memory card swap failed." );
423 Console.Indent().WriteLn( L"Src : " + srcfile.GetFullPath() );
424 Console.Indent().WriteLn( L"Dest: " + destfile.GetFullPath() );
425 }
426 }
427
428 return def;
429 }
430 };
431
432 enum McdMenuId
433 {
434 McdMenuId_Create = 0x888,
435 McdMenuId_Mount,
436 McdMenuId_Relocate,
437 McdMenuId_RefreshList
438 };
439
440 // =====================================================================================================
441 // MemoryCardListPanel_Simple (implementations)
442 // =====================================================================================================
443 Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent )
444 : _parent( parent )
445 {
446 m_MultitapEnabled[0] = false;
447 m_MultitapEnabled[1] = false;
448
449 m_listview = new MemoryCardListView_Simple(this);
450 m_listview->SetMinSize(wxSize(m_listview->GetMinWidth(), m_listview->GetCharHeight() * 8));
451 m_listview->SetDropTarget( new McdDropTarget(m_listview) );
452
453 m_button_Create = new wxButton(this, wxID_ANY, _("Create"));
454 m_button_Mount = new wxButton(this, wxID_ANY, _("Mount"));
455
456 // ------------------------------------
457 // Sizer / Layout Section
458 // ------------------------------------
459
460 CreateLayout();
461
462 *s_leftside_buttons += m_button_Create;
463 *s_leftside_buttons += 2;
464 *s_leftside_buttons += m_button_Mount;
465 //*s_leftside_buttons += 2;
466
467 Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListPanel_Simple::OnListDrag));
468 Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(MemoryCardListPanel_Simple::OnListSelectionChanged));
469 Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler(MemoryCardListPanel_Simple::OnListSelectionChanged));
470
471 Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEventHandler(MemoryCardListPanel_Simple::OnOpenItemContextMenu) );
472
473 Connect( m_button_Mount->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard));
474 Connect( m_button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateCard));
475
476 // Popup Menu Connections!
477
478 Connect( McdMenuId_Create, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateCard) );
479 Connect( McdMenuId_Mount, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard) );
480 Connect( McdMenuId_Relocate, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRelocateCard) );
481 Connect( McdMenuId_RefreshList, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnRefreshSelections) );
482 }
483
484 void Panels::MemoryCardListPanel_Simple::UpdateUI()
485 {
486 if( !m_listview ) return;
487
488 int sel = m_listview->GetFirstSelected();
489
490 if( wxNOT_FOUND == sel )
491 {
492 m_button_Create->Disable();
493 m_button_Mount->Disable();
494 return;
495 }
496
497 const McdListItem& item( m_Cards[sel] );
498
499 m_button_Create->Enable();
500 m_button_Create->SetLabel( item.IsPresent ? _("Delete") : _("Create") );
501 pxSetToolTip( m_button_Create,
502 item.IsPresent
503 ? _("Deletes the existing memory card from disk (all contents are lost)." )
504 : _("Creates a new memory card in the empty slot." )
505 );
506
507 m_button_Mount->Enable( item.IsPresent );
508 m_button_Mount->SetLabel( item.IsEnabled ? _("Disable") : _("Enable") );
509 pxSetToolTip( m_button_Mount,
510 item.IsEnabled
511 ? _("Disables the selected memory card, so that it will not be seen by games or BIOS.")
512 : _("Mounts the selected memory card, so that games can see it again.")
513 );
514
515 }
516
517 void Panels::MemoryCardListPanel_Simple::Apply()
518 {
519 _parent::Apply();
520
521 ScopedCoreThreadClose closed_core;
522 closed_core.AllowResume();
523
524 for( uint slot=0; slot<8; ++slot )
525 {
526 g_Conf->Mcd[slot].Enabled = m_Cards[slot].IsEnabled && m_Cards[slot].IsPresent;
527 }
528 }
529
530 void Panels::MemoryCardListPanel_Simple::AppStatusEvent_OnSettingsApplied()
531 {
532 for( uint slot=0; slot<8; ++slot )
533 {
534 m_Cards[slot].IsEnabled = g_Conf->Mcd[slot].Enabled;
535 }
536
537 _parent::AppStatusEvent_OnSettingsApplied();
538 }
539
540 bool Panels::MemoryCardListPanel_Simple::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
541 {
542 if( filenames.GetCount() == 1 && wxFileName(filenames[0]).IsDir() )
543 {
544 m_FolderPicker->SetPath( filenames[0] );
545 return true;
546 }
547 return false;
548 }
549
550 bool Panels::MemoryCardListPanel_Simple::ValidateEnumerationStatus()
551 {
552 if( m_listview ) m_listview->SetMcdProvider( NULL );
553 return false;
554 }
555
556 void Panels::MemoryCardListPanel_Simple::DoRefresh()
557 {
558 for( uint slot=0; slot<8; ++slot )
559 {
560 if( FileMcd_IsMultitapSlot(slot) && !m_MultitapEnabled[FileMcd_GetMtapPort(slot)] ) continue;
561
562 wxFileName fullpath( m_FolderPicker->GetPath() + g_Conf->Mcd[slot].Filename.GetFullName() );
563 EnumerateMemoryCard( m_Cards[slot], fullpath );
564 m_Cards[slot].Slot = slot;
565 }
566
567 if( m_listview ) m_listview->SetMcdProvider( this );
568 UpdateUI();
569 }
570
571 void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt)
572 {
573 ScopedCoreThreadClose closed_core;
574
575 const int slot = m_listview->GetFirstSelected();
576 if( wxNOT_FOUND == slot ) return;
577
578 if( m_Cards[slot].IsPresent )
579 {
580 wxWindowID result = wxID_YES;
581 if( m_Cards[slot].IsFormatted )
582 {
583 wxString content;
584 content.Printf(
585 pxE( "!Notice:Mcd:Delete",
586 L"You are about to delete the formatted memory card in slot %u. "
587 L"All data on this card will be lost! Are you absolutely and quite positively sure?"
588 ), slot
589 );
590
591 result = Msgbox::YesNo( content, _("Delete memory card?") );
592 }
593
594 if( result == wxID_YES )
595 {
596 wxFileName fullpath( m_FolderPicker->GetPath() + g_Conf->Mcd[slot].Filename.GetFullName() );
597 wxRemoveFile( fullpath.GetFullPath() );
598 }
599 }
600 else
601 {
602 wxWindowID result = Dialogs::CreateMemoryCardDialog( this, slot, m_FolderPicker->GetPath() ).ShowModal();
603 m_Cards[slot].IsEnabled = (result != wxID_CANCEL);
604 }
605
606 RefreshSelections();
607 closed_core.AllowResume();
608 }
609
610 /*void Panels::MemoryCardListPanel_Simple::OnSwapPorts(wxCommandEvent& evt)
611 {
612
613 }*/
614
615 void Panels::MemoryCardListPanel_Simple::OnMountCard(wxCommandEvent& evt)
616 {
617 evt.Skip();
618
619 const int slot = m_listview->GetFirstSelected();
620 if( wxNOT_FOUND == slot ) return;
621
622 m_Cards[slot].IsEnabled = !m_Cards[slot].IsEnabled;
623 m_listview->RefreshItem(slot);
624 UpdateUI();
625 }
626
627 void Panels::MemoryCardListPanel_Simple::OnRelocateCard(wxCommandEvent& evt)
628 {
629 evt.Skip();
630
631 const int slot = m_listview->GetFirstSelected();
632 if( wxNOT_FOUND == slot ) return;
633
634 // Issue a popup to the user that allows them to pick a new .PS2 file to serve as
635 // the new host memorycard file for the slot. The dialog has a number of warnings
636 // present to reiterate that this is an advanced operation that PCSX2 may not
637 // support very well (ie, might be buggy).
638
639 m_listview->RefreshItem(slot);
640 UpdateUI();
641 }
642
643 void Panels::MemoryCardListPanel_Simple::OnListDrag(wxListEvent& evt)
644 {
645 int selection = m_listview->GetFirstSelected();
646
647 if( selection < 0 ) return;
648 McdDataObject my_data( selection );
649
650 wxDropSource dragSource( m_listview );
651 dragSource.SetData( my_data );
652 wxDragResult result = dragSource.DoDragDrop( wxDrag_AllowMove );
653 }
654
655 void Panels::MemoryCardListPanel_Simple::OnListSelectionChanged(wxListEvent& evt)
656 {
657 UpdateUI();
658 }
659
660 void Panels::MemoryCardListPanel_Simple::OnOpenItemContextMenu(wxListEvent& evt)
661 {
662 int idx = evt.GetIndex();
663
664 wxMenu* junk = new wxMenu();
665
666 if( idx != wxNOT_FOUND )
667 {
668 const McdListItem& item( m_Cards[idx] );
669
670 junk->Append( McdMenuId_Create, item.IsPresent ? _("Delete") : _("Create new...") );
671 junk->Append( McdMenuId_Mount, item.IsEnabled ? _("Disable") : _("Enable") );
672 junk->Append( McdMenuId_Relocate, _("Relocate file...") );
673
674 junk->AppendSeparator();
675 }
676
677 junk->Append( McdMenuId_RefreshList, _("Refresh List") );
678
679 PopupMenu( junk );
680 m_listview->RefreshItem( idx );
681 UpdateUI();
682 }
683
684 // Interface Implementation for IMcdList
685 int Panels::MemoryCardListPanel_Simple::GetLength() const
686 {
687 uint baselen = 2;
688 if( m_MultitapEnabled[0] ) baselen += 3;
689 if( m_MultitapEnabled[1] ) baselen += 3;
690 return baselen;
691 }
692
693 const McdListItem& Panels::MemoryCardListPanel_Simple::GetCard( int idx ) const
694 {
695 return m_Cards[idx];
696 }
697
698 McdListItem& Panels::MemoryCardListPanel_Simple::GetCard( int idx )
699 {
700 return m_Cards[idx];
701 }

  ViewVC Help
Powered by ViewVC 1.1.22