wxgui: Fixed most of the trivial bugs from the prev commit.

* Removed NoncopyableObject class and replaced it with a DeclareNoncopyableObject() macro -- which reports saner C++ compilation errors when the object copy is attempted.
 * Improved first run wizard and several configuration panels.
 * Moved the BIOS selector to its own menu item and dialog box, separate of the Settings panel.
 * Fixed various bugs preventing configuration changes from being saved.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1658 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-08-20 14:34:48 +00:00
parent 3c4b1afb49
commit 4b320294fc
37 changed files with 1037 additions and 556 deletions

View File

@ -420,6 +420,14 @@
RelativePath="..\..\include\Utilities\WinVersion.h" RelativePath="..\..\include\Utilities\WinVersion.h"
> >
</File> </File>
<File
RelativePath="..\..\include\Utilities\wxBaseTools.h"
>
</File>
<File
RelativePath="..\..\include\Utilities\wxGuiTools.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Resource Files" Name="Resource Files"

View File

@ -18,9 +18,62 @@
#pragma once #pragma once
//////////////////////////////////////////////////////////////////////////////////////////
// DeclareNoncopyableObject
// This macro provides an easy and clean method for ensuring objects are not copyable.
// Simply add the macro to the head or tail of your class declaration, and attempts to
// copy the class will give you a moderately obtuse compiler error that will have you
// scratching your head for 20 mintes.
//
// (... but that's probably better than having a weird invalid object copy having you
// scratch your head for a day).
//
// Programmer's notes:
// * We intentionally do NOT provide implementations for these methods, which should
// never be referenced anyway.
// * I've opted for macro form over multi-inherited class form (Boost style), because
// the errors generated by the macro are considerably less voodoo. The Boost-style
// The macro reports the exact class that causes the copy failure, while Boost's class
// approach just reports an error in whatever "NoncopyableObject" is inherited.
//
// * This macro is the same as wxWidgets' DECLARE_NO_COPY_CLASS macro. This one is free
// of wx dependencies though, and has a nicer typeset. :)
//
#ifndef DeclareNoncopyableObject
# define DeclareNoncopyableObject(classname) \
private: \
explicit classname(const classname&); \
classname& operator=(const classname&);
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// __BaseSealed
// Base class used to implement type-safe sealed classes.
// This class should never be used directly. Use the Sealed macro instead, which ensures
// all sealed classes derive from a unique BaseSealed (preventing them from accidentally
// circumventing sealing by inheriting from multiple sealed classes.
//
template < int T >
class __BaseSealed
{
protected:
__BaseSealed()
{
}
};
// Use this macro/class as a base to seal a class from being derived from.
// This macro works by providing a unique base class with a protected constructor
// for every class that derives from it.
#define Sealed private virtual __BaseSealed<__COUNTER__>
//////////////////////////////////////////////////////////////////////////////////////////
// macro provided for tagging translation strings, without actually running them through the // macro provided for tagging translation strings, without actually running them through the
// translator (which the _() does automatically, and sometimes we don't want that). This is // translator (which the _() does automatically, and sometimes we don't want that). This is
// a shorthand replacement for wxTRANSLATE. // a shorthand replacement for wxTRANSLATE.
//
#define wxLt(a) (a) #define wxLt(a) (a)
#ifndef wxASSERT_MSG_A #ifndef wxASSERT_MSG_A

View File

@ -22,45 +22,6 @@
extern void DevAssert( bool condition, const char* msg ); extern void DevAssert( bool condition, const char* msg );
//////////////////////////////////////////////////////////////////////////////////////////
// This class provides an easy and clean method for ensuring objects are not copyable.
//
class NoncopyableObject
{
protected:
NoncopyableObject() {}
~NoncopyableObject() {} // intentionally non-virtual (code should never use this as a polymorphic type)
// Programmer's note:
// No need to provide implementations for these methods since they should
// never be referenced anyway. No references? No Linker Errors! Noncopyable!
private:
// Copy me? I think not!
explicit NoncopyableObject( const NoncopyableObject& );
// Assign me? I think not!
const NoncopyableObject& operator=( const NoncopyableObject& );
};
//////////////////////////////////////////////////////////////////////////////////////////
// Base class used to implement type-safe sealed classes.
// This class should never be used directly. Use the Sealed macro instead, which ensures
// all sealed classes derive from a unique BaseSealed (preventing them from accidentally
// circumventing sealing by inheriting from multiple sealed classes.
//
template < int T >
class __BaseSealed
{
protected:
__BaseSealed()
{
}
};
// Use this macro/class as a base to seal a class from being derived from.
// This macro works by providing a unique base class with a protected constructor
// for every class that derives from it.
#define Sealed private virtual __BaseSealed<__COUNTER__>
namespace Exception namespace Exception
{ {
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////

View File

@ -63,8 +63,10 @@ extern void pcsx2_aligned_free(void* pmem);
// exception-based error handling and automatic cleanup. // exception-based error handling and automatic cleanup.
// //
template< typename T > template< typename T >
class SafeArray : public NoncopyableObject class SafeArray
{ {
DeclareNoncopyableObject(SafeArray)
public: public:
static const int DefaultChunkSize = 0x1000 * sizeof(T); static const int DefaultChunkSize = 0x1000 * sizeof(T);
@ -218,8 +220,10 @@ protected:
// * Classes with destructors (they're not called, sorry!) // * Classes with destructors (they're not called, sorry!)
// //
template< typename T > template< typename T >
class SafeList : public NoncopyableObject class SafeList
{ {
DeclareNoncopyableObject(SafeList)
public: public:
static const int DefaultChunkSize = 0x80 * sizeof(T); static const int DefaultChunkSize = 0x80 * sizeof(T);

View File

@ -117,8 +117,10 @@ namespace Threading
// no dependency options for ensuring correct static var initializations). Use heap // no dependency options for ensuring correct static var initializations). Use heap
// allocation to create thread objects instead. // allocation to create thread objects instead.
// //
class PersistentThread : NoncopyableObject class PersistentThread
{ {
DeclareNoncopyableObject(PersistentThread)
protected: protected:
typedef int (*PlainJoeFP)(); typedef int (*PlainJoeFP)();
pthread_t m_thread; pthread_t m_thread;
@ -169,8 +171,10 @@ namespace Threading
// Using this class provides an exception-safe (and generally clean) method of locking // Using this class provides an exception-safe (and generally clean) method of locking
// code inside a function or conditional block. // code inside a function or conditional block.
// //
class ScopedLock : public NoncopyableObject class ScopedLock
{ {
DeclareNoncopyableObject(ScopedLock)
protected: protected:
MutexLock& m_lock; MutexLock& m_lock;
bool m_IsLocked; bool m_IsLocked;

View File

@ -0,0 +1,59 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
#include "Dependencies.h"
// ----------------------------------------------------------------------------
// wxBaseTools.h
//
// This file is meant to contain utility classes for users of the wxWidgets library.
// All classes in this file are strictly dependent on wxBase libraries only, meaning
// you don't need to include or link against wxCore (GUI) to build them. For tools
// which require wxCore, see wxGuiTools.h
// ----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////////////
// wxDoNotLogInThisScope
// This class is used to disable wx's sometimes inappropriate amount of forced error logging
// during specific activities. For example, when using wxDynamicLibrary to detect the
// validity of DLLs, wx will log errors for missing symbols. (sigh)
//
// Usage: Basic auto-cleanup destructor class. Create an instance inside a scope, and
// logging will be re-enabled when scope is terminated. :)
//
class wxDoNotLogInThisScope
{
DeclareNoncopyableObject(wxDoNotLogInThisScope);
protected:
bool m_prev;
public:
wxDoNotLogInThisScope() :
m_prev( wxLog::EnableLogging( false ) )
{
}
~wxDoNotLogInThisScope()
{
wxLog::EnableLogging( m_prev );
}
};

View File

@ -0,0 +1,124 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
#include "Dependencies.h"
// ----------------------------------------------------------------------------
// wxGuiTools.h
//
// This file is meant to contain utility classes for users of the wxWidgets library.
// All classes in this file are dependent on wxBase and wxCore libraries! Meaning
// you will have to use wxCore header files and link against wxCore (GUI) to build
// them. For tools which require only wxBase, see wxBaseTools.h
// ----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////////////
// pxTextWrapperBase
// this class is used to wrap the text on word boundary: wrapping is done by calling
// OnStartLine() and OnOutputLine() functions. This class by itself can be used as a
// line counting tool, but produces no formatted text output.
//
// [class "borrowed" from wxWidgets private code, made public, and renamed to avoid possible
// conflicts with future editions of wxWidgets which might make it public. Why this isn't
// publicly available already in wxBase I'll never know-- air]
//
class pxTextWrapperBase
{
protected:
bool m_eol;
int m_linecount;
public:
virtual ~pxTextWrapperBase() { }
pxTextWrapperBase() :
m_eol( false )
, m_linecount( 0 )
{
}
// win is used for getting the font, text is the text to wrap, width is the
// max line width or -1 to disable wrapping
void Wrap( const wxWindow *win, const wxString& text, int widthMax );
int GetLineCount() const
{
return m_linecount;
}
protected:
// line may be empty
virtual void OnOutputLine(const wxString& line) { }
// called at the start of every new line (except the very first one)
virtual void OnNewLine() { }
void DoOutputLine(const wxString& line)
{
OnOutputLine(line);
m_linecount++;
m_eol = true;
}
// this function is a destructive inspector: when it returns true it also
// resets the flag to false so calling it again wouldn't return true any
// more
bool IsStartOfNewLine()
{
if ( !m_eol )
return false;
m_eol = false;
return true;
}
};
//////////////////////////////////////////////////////////////////////////////////////////
// pxTextWrapper
// This class extends pxTextWrapperBase and adds the ability to retrieve the formatted
// result of word wrapping.
//
class pxTextWrapper : public pxTextWrapperBase
{
protected:
wxString m_text;
public:
pxTextWrapper() : pxTextWrapperBase()
, m_text()
{
}
const wxString& GetResult() const
{
return m_text;
}
protected:
virtual void OnOutputLine(const wxString& line)
{
m_text += line;
}
virtual void OnNewLine()
{
m_text += L'\n';
}
};

View File

@ -636,8 +636,10 @@ __forceinline void xWrite( T val )
// speed benefits in the form of L1/L2 cache clutter, on any CPU. They're also notably // speed benefits in the form of L1/L2 cache clutter, on any CPU. They're also notably
// faster on P4's, and mildly faster on AMDs. (Core2's and i7's don't care) // faster on P4's, and mildly faster on AMDs. (Core2's and i7's don't care)
// //
class xSmartJump : public NoncopyableObject class xSmartJump
{ {
DeclareNoncopyableObject(xSmartJump)
protected: protected:
u8* m_baseptr; // base address of the instruction (passed to the instruction emitter) u8* m_baseptr; // base address of the instruction (passed to the instruction emitter)
JccComparisonType m_cc; // comparison type of the instruction JccComparisonType m_cc; // comparison type of the instruction

View File

@ -47,15 +47,15 @@ const PluginInfo tbl_PluginInfo[] =
}; };
int EnumeratePluginsFolder( wxArrayString* dest ) int EnumeratePluginsInFolder( wxDirName& searchpath, wxArrayString* dest )
{ {
wxScopedPtr<wxArrayString> placebo; wxScopedPtr<wxArrayString> placebo;
wxArrayString* realdest = dest; wxArrayString* realdest = dest;
if( realdest == NULL ) if( realdest == NULL )
placebo.reset( realdest = new wxArrayString() ); placebo.reset( realdest = new wxArrayString() );
return g_Conf->Folders.Plugins.Exists() ? return searchpath.Exists() ?
wxDir::GetAllFiles( g_Conf->Folders.Plugins.ToString(), realdest, wxsFormat( L"*%s", wxDynamicLibrary::GetDllExt()), wxDIR_FILES ) : 0; wxDir::GetAllFiles( searchpath.ToString(), realdest, wxsFormat( L"*%s", wxDynamicLibrary::GetDllExt()), wxDIR_FILES ) : 0;
} }

View File

@ -109,7 +109,7 @@ protected:
extern const PluginInfo tbl_PluginInfo[]; extern const PluginInfo tbl_PluginInfo[];
extern PluginManager* g_plugins; extern PluginManager* g_plugins;
extern int EnumeratePluginsFolder( wxArrayString* dest ); extern int EnumeratePluginsInFolder( wxDirName& searchPath, wxArrayString* dest );
void LoadPlugins(); void LoadPlugins();

View File

@ -77,6 +77,7 @@ typedef int BOOL;
#include "i18n.h" #include "i18n.h"
#include "Paths.h" #include "Paths.h"
#include "Config.h" #include "Config.h"
#include "Utilities/wxBaseTools.h"
#include "Utilities/Console.h" #include "Utilities/Console.h"
#include "Utilities/Exceptions.h" #include "Utilities/Exceptions.h"
#include "Utilities/MemcpyFast.h" #include "Utilities/MemcpyFast.h"

View File

@ -92,4 +92,7 @@ namespace Msgbox
extern bool OkCancel( const wxString& text ); extern bool OkCancel( const wxString& text );
} }
DECLARE_EVENT_TYPE( pxEVT_MSGBOX, -1 ); BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE( pxEVT_MSGBOX, -1 );
END_DECLARE_EVENT_TYPES()

View File

@ -66,14 +66,18 @@ public:
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
class ConsoleLogFrame : public wxFrame, public NoncopyableObject class ConsoleLogFrame : public wxFrame
{ {
DeclareNoncopyableObject(ConsoleLogFrame)
public: public:
typedef AppConfig::ConsoleLogOptions ConLogConfig; typedef AppConfig::ConsoleLogOptions ConLogConfig;
protected: protected:
class ColorArray : public NoncopyableObject class ColorArray
{ {
DeclareNoncopyableObject(ColorArray)
protected: protected:
SafeArray<wxTextAttr> m_table; SafeArray<wxTextAttr> m_table;
wxTextAttr m_color_default; wxTextAttr m_color_default;

View File

@ -178,7 +178,7 @@ const wxDirName& AppConfig::FolderOptions::operator[]( FoldersEnum_t folderidx )
jNO_DEFAULT jNO_DEFAULT
} }
return Plugins; // unreachable, but supresses warnings. return Plugins; // unreachable, but suppresses warnings.
} }
const bool AppConfig::FolderOptions::IsDefault( FoldersEnum_t folderidx ) const const bool AppConfig::FolderOptions::IsDefault( FoldersEnum_t folderidx ) const
@ -346,6 +346,12 @@ wxString AppConfig::FullpathTo( PluginsEnum_t pluginidx ) const
return Path::Combine( Folders.Plugins, BaseFilenames[pluginidx] ); return Path::Combine( Folders.Plugins, BaseFilenames[pluginidx] );
} }
wxString AppConfig::FullPathToConfig() const
{
return g_Conf->Folders.Settings.Combine( FilenameDefs::GetConfig() ).GetFullPath();
}
wxString AppConfig::FullpathToBios() const { return Path::Combine( Folders.Bios, BaseFilenames.Bios ); } wxString AppConfig::FullpathToBios() const { return Path::Combine( Folders.Bios, BaseFilenames.Bios ); }
wxString AppConfig::FullpathToMcd( uint mcdidx ) const { return Path::Combine( Folders.MemoryCards, Mcd[mcdidx].Filename ); } wxString AppConfig::FullpathToMcd( uint mcdidx ) const { return Path::Combine( Folders.MemoryCards, Mcd[mcdidx].Filename ); }
@ -414,7 +420,9 @@ void AppConfig::LoadSave( IniInterface& ini )
// //
void AppConfig::Apply() void AppConfig::Apply()
{ {
if( !m_IsLoaded ) return; Folders.ApplyDefaults();
if( NULL == wxConfigBase::Get( false ) ) return;
// Ensure existence of necessary documents folders. Plugins and other parts // Ensure existence of necessary documents folders. Plugins and other parts
// of PCSX2 rely on them. // of PCSX2 rely on them.
@ -428,16 +436,17 @@ void AppConfig::Apply()
NTFS_CompressFile( Folders.MemoryCards.ToString(), McdEnableNTFS ); NTFS_CompressFile( Folders.MemoryCards.ToString(), McdEnableNTFS );
bool prev = wxLog::EnableLogging( false ); // wx generates verbose errors if languages don't exist, so disable them here.
if( !i18n_SetLanguage( LanguageId ) )
{ {
if( !i18n_SetLanguage( wxLANGUAGE_DEFAULT ) ) wxDoNotLogInThisScope please;
if( !i18n_SetLanguage( LanguageId ) )
{ {
i18n_SetLanguage( wxLANGUAGE_ENGLISH ); if( !i18n_SetLanguage( wxLANGUAGE_DEFAULT ) )
{
i18n_SetLanguage( wxLANGUAGE_ENGLISH );
}
} }
} }
wxLog::EnableLogging( prev );
// Always perform delete and reload of the Recent Iso List. This handles cases where // Always perform delete and reload of the Recent Iso List. This handles cases where
// the recent file count has been changed, and it's a helluva lot easier than trying // the recent file count has been changed, and it's a helluva lot easier than trying
// to make a clone copy of this complex object. ;) // to make a clone copy of this complex object. ;)
@ -457,6 +466,8 @@ void AppConfig::Apply()
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void AppConfig::Load() void AppConfig::Load()
{ {
if( NULL == wxConfigBase::Get( false ) ) return;
m_IsLoaded = true; m_IsLoaded = true;
// Note: Extra parenthesis resolves "I think this is a function" issues with C++. // Note: Extra parenthesis resolves "I think this is a function" issues with C++.
@ -466,7 +477,7 @@ void AppConfig::Load()
void AppConfig::Save() void AppConfig::Save()
{ {
if( !m_IsLoaded ) return; if( NULL == wxConfigBase::Get( false ) ) return;
IniSaver saver( (IniSaver()) ); IniSaver saver( (IniSaver()) );
LoadSave( saver ); LoadSave( saver );
@ -603,8 +614,7 @@ void AppConfig_ReloadGlobalSettings( bool overwrite )
PathDefs::GetSettings().Mkdir(); PathDefs::GetSettings().Mkdir();
// Allow wx to use our config, and enforces auto-cleanup as well // Allow wx to use our config, and enforces auto-cleanup as well
wxString confile( g_Conf->Folders.Settings.Combine( FilenameDefs::GetConfig() ).GetFullPath() ); delete wxConfigBase::Set( OpenFileConfig( g_Conf->FullPathToConfig() ) );
delete wxConfigBase::Set( OpenFileConfig( confile ) );
wxConfigBase::Get()->SetRecordDefaults(); wxConfigBase::Get()->SetRecordDefaults();
if( !overwrite ) if( !overwrite )

View File

@ -150,6 +150,7 @@ public:
wxString FullpathToBios() const; wxString FullpathToBios() const;
wxString FullpathToMcd( uint mcdidx ) const; wxString FullpathToMcd( uint mcdidx ) const;
wxString FullpathTo( PluginsEnum_t pluginId ) const; wxString FullpathTo( PluginsEnum_t pluginId ) const;
wxString FullPathToConfig() const;
void Load(); void Load();
void Save(); void Save();

View File

@ -30,11 +30,12 @@
// who ever wrote the code of wxWidgets had a peculiar love of the 'private' keyword, // who ever wrote the code of wxWidgets had a peculiar love of the 'private' keyword,
// thus killing any possibility of subclassing in a useful manner. (sigh) // thus killing any possibility of subclassing in a useful manner. (sigh)
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(wxEVT_LOG_Write, -1) DECLARE_EVENT_TYPE(wxEVT_LOG_Write, -1)
DECLARE_EVENT_TYPE(wxEVT_LOG_Newline, -1) DECLARE_EVENT_TYPE(wxEVT_LOG_Newline, -1)
DECLARE_EVENT_TYPE(wxEVT_SetTitleText, -1) DECLARE_EVENT_TYPE(wxEVT_SetTitleText, -1)
DECLARE_EVENT_TYPE(wxEVT_SemaphoreWait, -1); DECLARE_EVENT_TYPE(wxEVT_SemaphoreWait, -1);
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE(wxEVT_LOG_Write) DEFINE_EVENT_TYPE(wxEVT_LOG_Write)
DEFINE_EVENT_TYPE(wxEVT_LOG_Newline) DEFINE_EVENT_TYPE(wxEVT_LOG_Newline)

View File

@ -25,6 +25,12 @@
#include "Panels/ConfigurationPanels.h" #include "Panels/ConfigurationPanels.h"
#include <wx/artprov.h> #include <wx/artprov.h>
#include <wx/listbook.h>
#include <wx/listctrl.h>
#ifdef __WXMSW__
# include <commctrl.h> // needed for Vista icon spacing fix.
#endif
using namespace wxHelpers; using namespace wxHelpers;
using namespace Panels; using namespace Panels;
@ -42,7 +48,7 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
wxDialogWithHelpers( parent, id, _("PCSX2 Configuration"), true ) wxDialogWithHelpers( parent, id, _("PCSX2 Configuration"), true )
, m_listbook( *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient ) ) , m_listbook( *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient ) )
{ {
static const int IdealWidth = 460; static const int IdealWidth = 500;
wxBoxSizer& mainSizer = *new wxBoxSizer( wxVERTICAL ); wxBoxSizer& mainSizer = *new wxBoxSizer( wxVERTICAL );
@ -67,15 +73,24 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
m_listbook.AddPage( new PluginSelectorPanel( m_listbook, IdealWidth ), _("Plugins"), false, cfgid.Plugins ); m_listbook.AddPage( new PluginSelectorPanel( m_listbook, IdealWidth ), _("Plugins"), false, cfgid.Plugins );
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() ); g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
m_listbook.AddPage( new TabbedPathsPanel( m_listbook, IdealWidth ), _("Folders"), false, cfgid.Paths ); m_listbook.AddPage( new StandardPathsPanel( m_listbook ), _("Folders"), false, cfgid.Paths );
mainSizer.Add( &m_listbook ); mainSizer.Add( &m_listbook );
AddOkCancel( mainSizer, true ); AddOkCancel( mainSizer, true );
SetSizerAndFit( &mainSizer ); SetSizerAndFit( &mainSizer );
CenterOnScreen(); CenterOnScreen();
#ifdef __WXMSW__
// Depending on Windows version and user appearance settings, the default icon spacing can be
// way over generous. This little bit of Win32-specific code ensures proper icon spacing, scaled
// to the size of the frame's ideal width.
ListView_SetIconSpacing( (HWND)m_listbook.GetListView()->GetHWND(),
(IdealWidth-6) / m_listbook.GetPageCount(), g_Conf->Listbook_ImageSize+32 // y component appears to be ignored
);
#endif
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) ); Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) ); Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) );
} }
@ -99,3 +114,26 @@ void Dialogs::ConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
evt.Skip(); evt.Skip();
g_ApplyState.ApplyAll(); g_ApplyState.ApplyAll();
} }
// ----------------------------------------------------------------------------
Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent ) :
wxDialogWithHelpers( parent, wxID_ANY, _("BIOS Selector"), false )
{
wxBoxSizer& bleh( *new wxBoxSizer( wxVERTICAL ) );
bleh.Add( new Panels::BiosSelectorPanel( *this, 500 ), SizerFlags::StdExpand() );
AddOkCancel( bleh, false );
SetSizerAndFit( &bleh );
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BiosSelectorDialog::OnOk_Click ) );
}
void Dialogs::BiosSelectorDialog::OnOk_Click( wxCommandEvent& evt )
{
if( g_ApplyState.ApplyAll() )
{
Close();
evt.Skip();
}
}

View File

@ -21,10 +21,11 @@
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/image.h> #include <wx/image.h>
#include <wx/propdlg.h> #include <wx/propdlg.h>
#include <wx/listbook.h>
#include "wxHelpers.h" #include "wxHelpers.h"
class wxListbook;
namespace Dialogs namespace Dialogs
{ {
class ConfigurationDialog : public wxDialogWithHelpers class ConfigurationDialog : public wxDialogWithHelpers
@ -40,4 +41,17 @@ namespace Dialogs
void OnOk_Click( wxCommandEvent& evt ); void OnOk_Click( wxCommandEvent& evt );
void OnApply_Click( wxCommandEvent& evt ); void OnApply_Click( wxCommandEvent& evt );
}; };
class BiosSelectorDialog : public wxDialogWithHelpers
{
protected:
public:
virtual ~BiosSelectorDialog() {}
BiosSelectorDialog(wxWindow* parent );
protected:
void OnOk_Click( wxCommandEvent& evt );
};
} }

View File

@ -22,6 +22,7 @@
#include "ModalPopups.h" #include "ModalPopups.h"
#include "Panels/ConfigurationPanels.h" #include "Panels/ConfigurationPanels.h"
#include "wx//file.h"
using namespace wxHelpers; using namespace wxHelpers;
using namespace Panels; using namespace Panels;
@ -33,55 +34,91 @@ static T& MakeWizWidget( int pageid, wxWizardPage& src )
return *new T( src, 620 ); return *new T( src, 620 );
} }
// ----------------------------------------------------------------------------
Panels::SettingsDirPickerPanel::SettingsDirPickerPanel( wxWindow* parent ) :
DirPickerPanel( parent, FolderId_Settings, _("Settings"), _("Select a folder for PCSX2 settings") )
{
SetToolTip( pxE( ".Tooltips:Folders:Settings",
L"This is the folder where PCSX2 saves your settings, including settings generated "
L"by most plugins (some older plugins may not respect this value)."
) );
// Insert this into the top of the staticboxsizer created by the constructor.
GetSizer()->Insert( 0,
new wxStaticText( this, wxID_ANY,
pxE( ".Dialogs:SettingsDirPicker",
L"You may optionally specify a location for your PCSX2 settings here. If the location \n"
L"contains existing PCSX2 settings, you will be given the option to import or overwrite them."
), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE
), wxSizerFlags().Expand().Border( wxBOTTOM, 6 )
);
SetSizerAndFit( GetSizer(), false );
}
// ----------------------------------------------------------------------------
FirstTimeWizard::UsermodePage::UsermodePage( wxWizard* parent ) :
wxWizardPageSimple( (g_ApplyState.SetCurrentPage( 0 ), parent) )
, m_dirpick_settings( *new SettingsDirPickerPanel( this ) )
, m_panel_LangSel( *new LanguageSelectionPanel( *this, 608 ) )
, m_panel_UserSel( *new UsermodeSelectionPanel( *this, 608 ) )
{
wxBoxSizer& usermodeSizer( *new wxBoxSizer( wxVERTICAL ) );
AddStaticTextTo( this, usermodeSizer, _("PCSX2 is starting from a new or unknown folder and needs to be configured.") );
usermodeSizer.Add( &m_panel_LangSel, SizerFlags::StdCenter() );
usermodeSizer.Add( &m_panel_UserSel, wxSizerFlags().Expand().Border( wxALL, 8 ) );
usermodeSizer.AddSpacer( 6 );
usermodeSizer.Add( &m_dirpick_settings, SizerFlags::SubGroup() );
SetSizerAndFit( &usermodeSizer );
Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(FirstTimeWizard::UsermodePage::OnUsermodeChanged) );
}
void FirstTimeWizard::UsermodePage::OnUsermodeChanged( wxCommandEvent& evt )
{
m_panel_UserSel.Apply( *g_Conf ); // this assigns the current user mode to g_ApplyState.UseAdminMode
if( g_ApplyState.UseAdminMode == UseAdminMode ) return;
UseAdminMode = g_ApplyState.UseAdminMode;
g_Conf->Folders.ApplyDefaults();
m_dirpick_settings.Reset();
}
// ----------------------------------------------------------------------------
FirstTimeWizard::FirstTimeWizard( wxWindow* parent ) : FirstTimeWizard::FirstTimeWizard( wxWindow* parent ) :
wxWizard( (g_ApplyState.StartWizard(), parent), wxID_ANY, _("PCSX2 First Time Configuration") ) wxWizard( (g_ApplyState.StartWizard(), parent), wxID_ANY, _("PCSX2 First Time Configuration") )
, m_page_usermode( *new wxWizardPageSimple( this ) ) , m_page_usermode( *new UsermodePage( this ) )
//, m_page_paths( *new wxWizardPageSimple( this, &m_page_usermode ) )
, m_page_plugins( *new wxWizardPageSimple( this, &m_page_usermode ) ) , m_page_plugins( *new wxWizardPageSimple( this, &m_page_usermode ) )
, m_page_bios( *new wxWizardPageSimple( this, &m_page_plugins ) )
, m_panel_LangSel( MakeWizWidget<LanguageSelectionPanel>( 0, m_page_usermode ) )
, m_panel_UsermodeSel( MakeWizWidget<UsermodeSelectionPanel>( 0, m_page_usermode ) )
, m_panel_Paths( MakeWizWidget<AdvancedPathsPanel>( 0, m_page_usermode ) )
, m_panel_PluginSel( MakeWizWidget<PluginSelectorPanel>( 1, m_page_plugins ) ) , m_panel_PluginSel( MakeWizWidget<PluginSelectorPanel>( 1, m_page_plugins ) )
, m_panel_BiosSel( MakeWizWidget<BiosSelectorPanel>( 2, m_page_bios ) )
{ {
// Page 1 - User Mode and Language Selectors // Page 2 - Plugins Panel
wxBoxSizer& usermodeSizer( *new wxBoxSizer( wxVERTICAL ) );
AddStaticTextTo( &m_page_usermode, usermodeSizer, _("PCSX2 is starting from a new or unknown folder and needs to be configured.") );
usermodeSizer.Add( &m_panel_LangSel, SizerFlags::StdCenter() );
usermodeSizer.Add( &m_panel_UsermodeSel, wxSizerFlags().Expand().Border( wxALL, 8 ) );
//AddStaticTextTo( this, usermodeSizer, _( "Advanced users can optionally configure these folders." ) );
usermodeSizer.AddSpacer( 6 );
usermodeSizer.Add( &m_panel_Paths, wxSizerFlags().Expand().Border( wxALL, 4 ) );
m_page_usermode.SetSizerAndFit( &usermodeSizer );
// Page 2 - Advanced Paths Panel
/*wxBoxSizer& pathsSizer( *new wxBoxSizer( wxVERTICAL ) );
pathsSizer.Add( &m_panel_Paths, SizerFlags::StdExpand() );
m_page_paths.SetSizerAndFit( &pathsSizer );*/
// Page 3 - Plugins Panel
wxBoxSizer& pluginSizer( *new wxBoxSizer( wxVERTICAL ) ); wxBoxSizer& pluginSizer( *new wxBoxSizer( wxVERTICAL ) );
pluginSizer.Add( &m_panel_PluginSel, SizerFlags::StdExpand() ); pluginSizer.Add( &m_panel_PluginSel, SizerFlags::StdExpand() );
m_page_plugins.SetSizerAndFit( &pluginSizer ); m_page_plugins.SetSizerAndFit( &pluginSizer );
// Assign page indexes as client data // Assign page indexes as client data
m_page_usermode.SetClientData ( (void*)0 ); m_page_usermode.SetClientData ( (void*)0 );
//m_page_paths.SetClientData ( (void*)1 );
m_page_plugins.SetClientData ( (void*)1 ); m_page_plugins.SetClientData ( (void*)1 );
m_page_bios.SetClientData ( (void*)2 );
// Build the forward chain: // Build the forward chain:
// (backward chain is built during initialization above) // (backward chain is built during initialization above)
m_page_usermode.SetNext ( &m_page_plugins ); m_page_usermode.SetNext ( &m_page_plugins );
//m_page_paths.SetNext ( &m_page_plugins ); m_page_plugins.SetNext ( &m_page_bios );
GetPageAreaSizer()->Add( &m_page_usermode ); GetPageAreaSizer()->Add( &m_page_usermode );
CenterOnScreen(); CenterOnScreen();
Connect( wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( FirstTimeWizard::OnPageChanged ) ); Connect( wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( FirstTimeWizard::OnPageChanged ) );
Connect( wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( FirstTimeWizard::OnPageChanging ) ); Connect( wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( FirstTimeWizard::OnPageChanging ) );
Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(FirstTimeWizard::OnUsermodeChanged) );
} }
FirstTimeWizard::~FirstTimeWizard() FirstTimeWizard::~FirstTimeWizard()
@ -91,47 +128,50 @@ FirstTimeWizard::~FirstTimeWizard()
void FirstTimeWizard::OnPageChanging( wxWizardEvent& evt ) void FirstTimeWizard::OnPageChanging( wxWizardEvent& evt )
{ {
if( evt.GetPage() == NULL ) return; // safety valve!
int page = (int)evt.GetPage()->GetClientData();
//evt.Skip(); //evt.Skip();
if( evt.GetDirection() ) if( evt.GetDirection() )
{ {
// Moving forward: // Moving forward:
// Apply settings from the current page... // Apply settings from the current page...
int page = (int)evt.GetPage()->GetClientData();
if( page >= 0 ) if( page >= 0 )
{ {
if( !g_ApplyState.ApplyPage( page ) ) if( !g_ApplyState.ApplyPage( page, false ) )
{ {
evt.Veto(); evt.Veto();
return; return;
} }
AppConfig_ReloadGlobalSettings( true ); // ... and overwrite any existing settings
// [TODO] : The user should be prompted if they want to overwrite existing
// settings or import them instead.
} }
if( page == 0 ) if( page == 0 )
{ {
// test plugins folder for validity. If it doesn't exist or is empty then if( wxFile::Exists( g_Conf->FullPathToConfig() ) )
// the user needs to "try again" :)
if( !g_Conf->Folders.Plugins.Exists() )
{ {
Msgbox::Alert( _( "The selected plugins folder does not exist. You must select a valid PCSX2 plugins folder that exists and contains plugins." ) ); // Asks the user if they want to import or overwrite the existing settings.
evt.Veto();
} Dialogs::ImportSettingsDialog modal( this );
else if( modal.ShowModal() != wxID_OK )
{
if( 0 == EnumeratePluginsFolder(NULL) )
{ {
Msgbox::Alert( _( "The selected plugins folder is empty. You must select a valid PCSX2 plugins folder that actually contains plugins." ) );
evt.Veto(); evt.Veto();
return;
} }
} }
} }
} }
else
{
// Moving Backward:
// Some specific panels need per-init actions canceled.
if( page == 1 )
{
m_panel_PluginSel.CancelRefresh();
}
}
} }
void FirstTimeWizard::OnPageChanged( wxWizardEvent& evt ) void FirstTimeWizard::OnPageChanged( wxWizardEvent& evt )
@ -139,19 +179,7 @@ void FirstTimeWizard::OnPageChanged( wxWizardEvent& evt )
// Plugin Selector needs a special OnShow hack, because Wizard child panels don't // Plugin Selector needs a special OnShow hack, because Wizard child panels don't
// receive any Show events >_< // receive any Show events >_<
if( (sptr)evt.GetPage() == (sptr)&m_page_plugins ) if( (sptr)evt.GetPage() == (sptr)&m_page_plugins )
m_panel_PluginSel.OnShow(); m_panel_PluginSel.OnShown();
}
void FirstTimeWizard::OnUsermodeChanged( wxCommandEvent& evt )
{
//wxLogError( L"Awesome" );
m_panel_UsermodeSel.Apply( *g_Conf ); // this assigns the current user mode to g_ApplyState.UseAdminMode
if( g_ApplyState.UseAdminMode == UseAdminMode ) return;
UseAdminMode = g_ApplyState.UseAdminMode;
g_Conf->Folders.ApplyDefaults();
m_panel_Paths.Reset();
} }
/* /*

View File

@ -0,0 +1,69 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "System.h"
#include "ModalPopups.h"
using namespace wxHelpers;
Dialogs::ImportSettingsDialog::ImportSettingsDialog( wxWindow* parent ) :
wxDialogWithHelpers( parent, wxID_ANY, L"Import Existing Settings?", false )
{
wxBoxSizer& sizer( *new wxBoxSizer( wxVERTICAL ) );
AddStaticText( sizer,
pxE( ".Popup:ImportExistingSettings",
L"Existing PCSX2 settings have been found in the configured settings folder. "
L"Would you like to import these settings or overwrite them with PCSX2 default values?"
L"\n\n(or press Cancel to select a different settings folder)"
),
wxALIGN_CENTRE, 400
);
wxBoxSizer& s_buttons = *new wxBoxSizer( wxHORIZONTAL );
wxButton* b_import = new wxButton( this, wxID_ANY, _("Import") );
wxButton* b_over = new wxButton( this, wxID_ANY, _("Overwrite") );
s_buttons.Add( b_import,SizerFlags::StdButton() );
s_buttons.AddSpacer( 16 );
s_buttons.Add( b_over, SizerFlags::StdButton() );
s_buttons.AddSpacer( 16 );
s_buttons.Add( new wxButton( this, wxID_CANCEL ), SizerFlags::StdButton() );
sizer.AddSpacer( 12 );
sizer.Add( &s_buttons, SizerFlags::StdCenter() );
SetSizerAndFit( &sizer );
Connect( b_import->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ImportSettingsDialog::OnImport_Click) );
Connect( b_over->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ImportSettingsDialog::OnOverwrite_Click) );
}
void Dialogs::ImportSettingsDialog::OnImport_Click( __unused wxCommandEvent& evt )
{
AppConfig_ReloadGlobalSettings( false ); // ... and import existing settings
EndModal( wxID_OK );
}
void Dialogs::ImportSettingsDialog::OnOverwrite_Click( __unused wxCommandEvent& evt )
{
AppConfig_ReloadGlobalSettings( true ); // ... and overwrite any existing settings
EndModal( wxID_OK );
}

View File

@ -116,7 +116,7 @@ LogOptionsDialog::iopLogOptionsPanel::iopLogOptionsPanel( wxWindow* parent ) :
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
LogOptionsDialog::LogOptionsDialog(wxWindow* parent, int id, const wxPoint& pos, const wxSize& size): LogOptionsDialog::LogOptionsDialog(wxWindow* parent, int id, const wxPoint& pos, const wxSize& size):
wxDialogWithHelpers( parent, id, L"Logging", true, pos, size ) wxDialogWithHelpers( parent, id, _("Logging"), true, pos, size )
{ {
eeLogOptionsPanel& eeBox = *new eeLogOptionsPanel( this ); eeLogOptionsPanel& eeBox = *new eeLogOptionsPanel( this );
iopLogOptionsPanel& iopSizer = *new iopLogOptionsPanel( this ); iopLogOptionsPanel& iopSizer = *new iopLogOptionsPanel( this );

View File

@ -33,8 +33,7 @@ public:
protected: protected:
///////////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------
//
class iopLogOptionsPanel : public CheckedStaticBox class iopLogOptionsPanel : public CheckedStaticBox
{ {
public: public:
@ -43,8 +42,7 @@ protected:
}; };
///////////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------
//
class eeLogOptionsPanel : public CheckedStaticBox class eeLogOptionsPanel : public CheckedStaticBox
{ {
public: public:
@ -72,8 +70,6 @@ public:
void LogChecked(wxCommandEvent &event); void LogChecked(wxCommandEvent &event);
protected: protected:
//DECLARE_EVENT_TABLE()
}; };
}; // end namespace Dialogs }; // end namespace Dialogs

View File

@ -26,25 +26,37 @@
class FirstTimeWizard : public wxWizard class FirstTimeWizard : public wxWizard
{ {
protected: protected:
wxWizardPageSimple& m_page_usermode; class UsermodePage : public wxWizardPageSimple
//wxWizardPageSimple& m_page_paths; {
wxWizardPageSimple& m_page_plugins; protected:
Panels::DirPickerPanel& m_dirpick_settings;
Panels::LanguageSelectionPanel& m_panel_LangSel;
Panels::UsermodeSelectionPanel& m_panel_UserSel;
public:
UsermodePage( wxWizard* parent );
protected:
void OnUsermodeChanged( wxCommandEvent& evt );
};
protected:
UsermodePage& m_page_usermode;
wxWizardPageSimple& m_page_plugins;
wxWizardPageSimple& m_page_bios;
Panels::LanguageSelectionPanel& m_panel_LangSel;
Panels::UsermodeSelectionPanel& m_panel_UsermodeSel;
Panels::AdvancedPathsPanel& m_panel_Paths;
Panels::PluginSelectorPanel& m_panel_PluginSel; Panels::PluginSelectorPanel& m_panel_PluginSel;
Panels::BiosSelectorPanel& m_panel_BiosSel;
public: public:
FirstTimeWizard( wxWindow* parent ); FirstTimeWizard( wxWindow* parent );
virtual ~FirstTimeWizard(); virtual ~FirstTimeWizard();
wxWizardPage *GetFirstPage() const { return &m_page_usermode; } wxWizardPage *GetFirstPage() const { return &m_page_usermode; }
protected: protected:
virtual void OnPageChanging( wxWizardEvent& evt ); virtual void OnPageChanging( wxWizardEvent& evt );
virtual void OnPageChanged( wxWizardEvent& evt ); virtual void OnPageChanged( wxWizardEvent& evt );
virtual void OnUsermodeChanged( wxCommandEvent& evt );
}; };
namespace Dialogs namespace Dialogs
@ -72,5 +84,17 @@ namespace Dialogs
protected: protected:
void OnOk_Click( wxCommandEvent& evt ); void OnOk_Click( wxCommandEvent& evt );
}; };
class ImportSettingsDialog : public wxDialogWithHelpers
{
public:
ImportSettingsDialog( wxWindow* parent );
protected:
void OnImport_Click( wxCommandEvent& evt );
void OnOverwrite_Click( wxCommandEvent& evt );
};
} }

View File

@ -96,7 +96,7 @@ void IniLoader::Entry( const wxString& var, bool& value, const bool defvalue )
// TODO : Stricter value checking on enabled/disabled? // TODO : Stricter value checking on enabled/disabled?
wxString dest; wxString dest;
m_Config.Read( var, &dest, defvalue ? L"enabled" : L"disabled" ); m_Config.Read( var, &dest, defvalue ? L"enabled" : L"disabled" );
value = (dest == L"enabled") || (dest != L"0"); value = (dest == L"enabled") || (dest == L"1");
} }
bool IniLoader::EntryBitBool( const wxString& var, bool value, const bool defvalue ) bool IniLoader::EntryBitBool( const wxString& var, bool value, const bool defvalue )

View File

@ -159,6 +159,7 @@ void MainEmuFrame::ConnectMenus()
Connect( id, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainEmuFrame::handler) ) Connect( id, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainEmuFrame::handler) )
ConnectMenu( Menu_Config_Settings, Menu_ConfigSettings_Click ); ConnectMenu( Menu_Config_Settings, Menu_ConfigSettings_Click );
ConnectMenu( Menu_Config_BIOS, Menu_SelectBios_Click );
ConnectMenu( Menu_IsoBrowse, Menu_RunIso_Click ); ConnectMenu( Menu_IsoBrowse, Menu_RunIso_Click );
ConnectMenu( Menu_RunWithoutDisc, Menu_RunWithoutDisc_Click ); ConnectMenu( Menu_RunWithoutDisc, Menu_RunWithoutDisc_Click );
@ -292,7 +293,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title):
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
m_menuConfig.Append(Menu_Config_Settings, _("Core Settings..."), wxEmptyString); m_menuConfig.Append(Menu_Config_Settings, _("Settings") );
m_menuConfig.AppendSeparator(); m_menuConfig.AppendSeparator();
// Query installed "tertiary" plugins for name and menu options. // Query installed "tertiary" plugins for name and menu options.
@ -302,7 +303,8 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title):
m_menuConfig.Append(Menu_Config_FireWire, _("Firewire"), wxEmptyString); m_menuConfig.Append(Menu_Config_FireWire, _("Firewire"), wxEmptyString);
m_menuConfig.AppendSeparator(); m_menuConfig.AppendSeparator();
m_menuConfig.Append(Menu_Config_Patches, _("Patches"), wxEmptyString); m_menuConfig.Append(Menu_Config_Patches, _("Patches"), wxEmptyString);
m_menuConfig.Append(Menu_Config_BIOS, _("BIOS") );
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -313,8 +315,8 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title):
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
m_menuMisc.Append( &m_MenuItem_Console ); m_menuMisc.Append( &m_MenuItem_Console );
m_menuMisc.Append(Menu_Patches, _("Enable Patches"), wxEmptyString, wxITEM_CHECK); m_menuMisc.Append(Menu_Patches, _("Enable Patches"), wxEmptyString, wxITEM_CHECK);
m_menuMisc.Append(Menu_Profiler,_("Enable Profiler"), wxEmptyString, wxITEM_CHECK); m_menuMisc.Append(Menu_Profiler, _("Enable Profiler"), wxEmptyString, wxITEM_CHECK);
m_menuMisc.AppendSeparator(); m_menuMisc.AppendSeparator();
// No dialogs implemented for these yet... // No dialogs implemented for these yet...
@ -324,12 +326,15 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title):
// Ref will want this re-added eventually. // Ref will want this re-added eventually.
//m_menuMisc.Append(47, _T("Print CDVD Info..."), wxEmptyString, wxITEM_CHECK); //m_menuMisc.Append(47, _T("Print CDVD Info..."), wxEmptyString, wxITEM_CHECK);
m_menuMisc.Append(Menu_About, _("About..."), wxEmptyString); m_menuMisc.Append(Menu_About, _("About...") );
m_menuMisc.Append(Menu_Website, _("Pcsx2 Website..."), _("Opens your web-browser!")); m_menuMisc.Append(Menu_Website, _("Pcsx2 Website..."), _("Opens your web-browser to our favorite website."));
m_menuDebug.Append(Menu_Debug_Open, _("Open Debug Window..."), wxEmptyString); m_menuDebug.Append(Menu_Debug_Open, _("Open Debug Window..."), wxEmptyString);
m_menuDebug.Append(Menu_Debug_MemoryDump, _("Memory Dump..."), wxEmptyString); m_menuDebug.Append(Menu_Debug_MemoryDump, _("Memory Dump..."), wxEmptyString);
m_menuDebug.Append(Menu_Debug_Logging, _("Logging..."), wxEmptyString); m_menuDebug.Append(Menu_Debug_Logging, _("Logging..."), wxEmptyString);
m_menuConfig.AppendSeparator();
m_menuDebug.Append(Menu_Debug_Usermode, _("Change Usermode..."), _(" Advanced feature for managing multiple concurrent PCSX2 environments."));
m_MenuItem_Console.Check( g_Conf->ProgLogBox.Visible ); m_MenuItem_Console.Check( g_Conf->ProgLogBox.Visible );

View File

@ -67,6 +67,7 @@ protected:
// Config Subsection // Config Subsection
Menu_Config_Settings = 100, Menu_Config_Settings = 100,
Menu_Config_BIOS,
Menu_Config_CDVD, Menu_Config_CDVD,
Menu_Config_DEV9, Menu_Config_DEV9,
Menu_Config_USB, Menu_Config_USB,
@ -105,6 +106,7 @@ protected:
Menu_Debug_Open = 600, // opens the debugger window / starts a debug session Menu_Debug_Open = 600, // opens the debugger window / starts a debug session
Menu_Debug_MemoryDump, Menu_Debug_MemoryDump,
Menu_Debug_Logging, // dialog for selection additional log options Menu_Debug_Logging, // dialog for selection additional log options
Menu_Debug_Usermode,
Menu_Languages, Menu_Languages,
// Language Menu // Language Menu
@ -155,6 +157,7 @@ protected:
void OnMoveAround( wxMoveEvent& evt ); void OnMoveAround( wxMoveEvent& evt );
void Menu_ConfigSettings_Click(wxCommandEvent &event); void Menu_ConfigSettings_Click(wxCommandEvent &event);
void Menu_SelectBios_Click(wxCommandEvent &event);
void Menu_RunIso_Click(wxCommandEvent &event); void Menu_RunIso_Click(wxCommandEvent &event);
void Menu_RunWithoutDisc_Click(wxCommandEvent &event); void Menu_RunWithoutDisc_Click(wxCommandEvent &event);

View File

@ -30,7 +30,18 @@ using namespace Dialogs;
void MainEmuFrame::Menu_ConfigSettings_Click(wxCommandEvent &event) void MainEmuFrame::Menu_ConfigSettings_Click(wxCommandEvent &event)
{ {
Dialogs::ConfigurationDialog( this ).ShowModal(); if( Dialogs::ConfigurationDialog( this ).ShowModal() )
{
g_Conf->Save();
}
}
void MainEmuFrame::Menu_SelectBios_Click(wxCommandEvent &event)
{
if( Dialogs::BiosSelectorDialog( this ).ShowModal() )
{
g_Conf->Save();
}
} }
static const wxChar* isoFilterTypes = static const wxChar* isoFilterTypes =

View File

@ -0,0 +1,155 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "ConfigurationPanels.h"
#include "Utilities/ScopedPtr.h"
#include "ps2/BiosTools.h"
#include <wx/dir.h>
using namespace wxHelpers;
// ------------------------------------------------------------------------
Panels::BaseSelectorPanel::BaseSelectorPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth )
{
Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(PluginSelectorPanel::OnFolderChanged), NULL, this );
}
Panels::BaseSelectorPanel::~BaseSelectorPanel()
{
}
void Panels::BaseSelectorPanel::OnShown()
{
if( !ValidateEnumerationStatus() )
DoRefresh();
}
bool Panels::BaseSelectorPanel::Show( bool visible )
{
if( visible )
OnShown();
return BaseApplicableConfigPanel::Show( visible );
}
void Panels::BaseSelectorPanel::OnRefresh( wxCommandEvent& evt )
{
ValidateEnumerationStatus();
DoRefresh();
}
void Panels::BaseSelectorPanel::OnFolderChanged( wxFileDirPickerEvent& evt )
{
evt.Skip();
OnShown();
}
// ----------------------------------------------------------------------------
Panels::BiosSelectorPanel::BiosSelectorPanel( wxWindow& parent, int idealWidth ) :
BaseSelectorPanel( parent, idealWidth-9 )
, m_ComboBox( *new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE | wxLB_SORT | wxLB_NEEDED_SB ) )
, m_FolderPicker( *new DirPickerPanel( this, FolderId_Bios,
_("BIOS Search Path:"), // static box label
_("Select folder with PS2 BIOS roms") // dir picker popup label
) )
, m_BiosList( NULL )
{
m_ComboBox.SetFont( wxFont( m_ComboBox.GetFont().GetPointSize()+1, wxFONTFAMILY_MODERN, wxNORMAL, wxNORMAL, false, L"Lucida Console" ) );
m_ComboBox.SetMinSize( wxSize( wxDefaultCoord, std::max( m_ComboBox.GetMinSize().GetHeight(), 96 ) ) );
wxBoxSizer& sizer( *new wxBoxSizer( wxVERTICAL ) );
AddStaticText( sizer, _("Select a BIOS rom:"), wxALIGN_LEFT );
sizer.Add( &m_ComboBox, SizerFlags::StdExpand() );
sizer.AddSpacer( 6 );
m_FolderPicker.SetStaticDesc( _("Click the Browse button to select a different folder where PCSX2 will look for PS2 BIOS roms.") );
sizer.Add( &m_FolderPicker, SizerFlags::StdExpand() );
SetSizerAndFit( &sizer );
}
Panels::BiosSelectorPanel::~BiosSelectorPanel()
{
safe_delete( m_BiosList );
}
bool Panels::BiosSelectorPanel::ValidateEnumerationStatus()
{
bool validated = true;
// Impl Note: ScopedPtr used so that resources get cleaned up if an exception
// occurs during file enumeration.
wxScopedPtr<wxArrayString> bioslist( new wxArrayString() );
if( m_FolderPicker.GetPath().Exists() )
wxDir::GetAllFiles( m_FolderPicker.GetPath().ToString(), bioslist.get(), L"*.bin", wxDIR_FILES );
if( (m_BiosList == NULL) || (*bioslist != *m_BiosList) )
validated = false;
delete m_BiosList;
m_BiosList = bioslist.release();
return validated;
}
void Panels::BiosSelectorPanel::Apply( AppConfig& conf )
{
int sel = m_ComboBox.GetSelection();
if( sel == wxNOT_FOUND )
{
throw Exception::CannotApplySettings( this,
// English Log
L"User did not specify a valid BIOS selection.",
// Translated
pxE( ".Popup Error:Invalid BIOS Selection",
L"Please select a valid BIOS before applying new settings. If you are unable to make\n"
L"a valid selection then press cancel to close the Configuration panel."
)
);
}
wxFileName relative( (*m_BiosList)[(int)m_ComboBox.GetClientData(sel)] );
relative.MakeRelativeTo( g_Conf->Folders.Bios.ToString() );
conf.BaseFilenames.Bios = relative.GetFullPath();
}
void Panels::BiosSelectorPanel::DoRefresh()
{
wxFileName right( g_Conf->FullpathToBios() );
right.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
for( size_t i=0; i<m_BiosList->GetCount(); ++i )
{
wxString description;
if( !IsBIOS((*m_BiosList)[i], description) ) continue;
int sel = m_ComboBox.Append( description, (void*)i );
wxFileName left( (*m_BiosList)[i] );
left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
if( left == right )
m_ComboBox.SetSelection( sel );
}
}

View File

@ -27,6 +27,8 @@
#include <wx/image.h> #include <wx/image.h>
#include <wx/statline.h> #include <wx/statline.h>
#include <wx/bookctrl.h> #include <wx/bookctrl.h>
#include <wx/listbox.h>
#include <list> #include <list>
#include "AppConfig.h" #include "AppConfig.h"
@ -118,7 +120,7 @@ namespace Panels
void StartBook( wxBookCtrlBase* book ); void StartBook( wxBookCtrlBase* book );
void StartWizard(); void StartWizard();
bool ApplyAll(); bool ApplyAll();
bool ApplyPage( int pageid ); bool ApplyPage( int pageid, bool saveOnSuccess=true );
void DoCleanup(); void DoCleanup();
}; };
@ -273,13 +275,27 @@ namespace Panels
public: public:
DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel ); DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel );
virtual ~DirPickerPanel() { }
void Apply( AppConfig& conf ); void Apply( AppConfig& conf );
void Reset(); void Reset();
wxDirName GetPath() const { return wxDirName( m_pickerCtrl->GetPath() ); }
DirPickerPanel& SetStaticDesc( const wxString& msg );
protected: protected:
void UseDefaultPath_Click(wxCommandEvent &event); void UseDefaultPath_Click( wxCommandEvent &event );
void Explore_Click( wxCommandEvent &event );
void UpdateCheckStatus( bool someNoteworthyBoolean ); void UpdateCheckStatus( bool someNoteworthyBoolean );
}; };
//////////////////////////////////////////////////////////////////////////////////////////
//
class SettingsDirPickerPanel : public DirPickerPanel
{
public:
SettingsDirPickerPanel( wxWindow* parent );
};
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
@ -290,7 +306,6 @@ namespace Panels
public: public:
BasePathsPanel( wxWindow& parent, int idealWidth=wxDefaultCoord ); BasePathsPanel( wxWindow& parent, int idealWidth=wxDefaultCoord );
virtual wxSizer& Sizer() { return s_main; }
protected: protected:
DirPickerPanel& AddDirPicker( wxBoxSizer& sizer, FoldersEnum_t folderid, DirPickerPanel& AddDirPicker( wxBoxSizer& sizer, FoldersEnum_t folderid,
@ -307,32 +322,46 @@ namespace Panels
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
class AdvancedPathsPanel : public BasePathsPanel class BaseSelectorPanel: public BaseApplicableConfigPanel
{ {
protected: protected:
DirPickerPanel& m_dirpick_plugins;
DirPickerPanel& m_dirpick_settings; public:
virtual ~BaseSelectorPanel();
BaseSelectorPanel( wxWindow& parent, int idealWidth );
virtual bool Show( bool visible=true );
virtual void OnRefresh( wxCommandEvent& evt );
virtual void OnShown();
virtual void OnFolderChanged( wxFileDirPickerEvent& evt );
protected:
virtual void DoRefresh()=0;
virtual bool ValidateEnumerationStatus()=0;
};
//////////////////////////////////////////////////////////////////////////////////////////
//
class BiosSelectorPanel : public BaseSelectorPanel
{
protected:
wxListBox& m_ComboBox;
DirPickerPanel& m_FolderPicker;
wxArrayString* m_BiosList;
public: public:
AdvancedPathsPanel( wxWindow& parent, int idealWidth ); BiosSelectorPanel( wxWindow& parent, int idealWidth );
void Reset(); virtual ~BiosSelectorPanel();
};
protected:
////////////////////////////////////////////////////////////////////////////////////////// virtual void Apply( AppConfig& conf );
// TabbedPathsPanel virtual void DoRefresh();
// This panel is a Tabbed (paged) panel which contains both Standard Paths and Advanced virtual bool ValidateEnumerationStatus();
// Paths panels.
//
class TabbedPathsPanel : public BaseApplicableConfigPanel
{
public:
TabbedPathsPanel( wxWindow& parent, int idealWidth );
void Apply( AppConfig& conf );
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
class PluginSelectorPanel: public BaseApplicableConfigPanel class PluginSelectorPanel: public BaseSelectorPanel
{ {
protected: protected:
static const int NumPluginTypes = 7; static const int NumPluginTypes = 7;
@ -365,6 +394,7 @@ namespace Panels
protected: protected:
PluginSelectorPanel& m_master; PluginSelectorPanel& m_master;
volatile bool m_cancel; volatile bool m_cancel;
public: public:
virtual ~EnumThread(); virtual ~EnumThread();
EnumThread( PluginSelectorPanel& master ); EnumThread( PluginSelectorPanel& master );
@ -380,12 +410,11 @@ namespace Panels
{ {
protected: protected:
wxComboBox* m_combobox[NumPluginTypes]; wxComboBox* m_combobox[NumPluginTypes];
wxComboBox& m_BiosBox; DirPickerPanel& m_FolderPicker;
public: public:
ComboBoxPanel( PluginSelectorPanel* parent ); ComboBoxPanel( PluginSelectorPanel* parent );
wxComboBox& Get( int i ) { return *m_combobox[i]; } wxComboBox& Get( int i ) { return *m_combobox[i]; }
wxComboBox& GetBios() { return m_BiosBox; } wxDirName GetPluginsPath() const { return m_FolderPicker.GetPath(); }
void Reset(); void Reset();
}; };
@ -410,7 +439,6 @@ namespace Panels
protected: protected:
wxArrayString* m_FileList; // list of potential plugin files wxArrayString* m_FileList; // list of potential plugin files
wxArrayString* m_BiosList;
StatusPanel& m_StatusPanel; StatusPanel& m_StatusPanel;
ComboBoxPanel& m_ComponentBoxes; ComboBoxPanel& m_ComponentBoxes;
EnumThread* m_EnumeratorThread; EnumThread* m_EnumeratorThread;
@ -418,18 +446,16 @@ namespace Panels
public: public:
virtual ~PluginSelectorPanel(); virtual ~PluginSelectorPanel();
PluginSelectorPanel( wxWindow& parent, int idealWidth ); PluginSelectorPanel( wxWindow& parent, int idealWidth );
virtual void OnProgress( wxCommandEvent& evt ); virtual void CancelRefresh();
virtual void OnEnumComplete( wxCommandEvent& evt );
void Apply( AppConfig& conf ); void Apply( AppConfig& conf );
void OnShow();
protected: protected:
virtual void OnShow( wxShowEvent& evt ); virtual void OnProgress( wxCommandEvent& evt );
virtual void OnRefresh( wxCommandEvent& evt ); virtual void OnEnumComplete( wxCommandEvent& evt );
void DoRefresh(); virtual void DoRefresh();
bool ValidateEnumerationStatus(); virtual bool ValidateEnumerationStatus();
int FileCount() const { return m_FileList->Count(); } int FileCount() const { return m_FileList->Count(); }
const wxString& GetFilename( int i ) const { return (*m_FileList)[i]; } const wxString& GetFilename( int i ) const { return (*m_FileList)[i]; }

View File

@ -0,0 +1,133 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "ConfigurationPanels.h"
#include <wx/stdpaths.h>
#include <wx/file.h>
#include <wx/dir.h>
using namespace wxHelpers;
static wxString GetNormalizedConfigFolder( FoldersEnum_t folderId )
{
const bool isDefault = g_Conf->Folders.IsDefault( folderId );
wxDirName normalized( isDefault ? PathDefs::Get(folderId) : g_Conf->Folders[folderId] );
normalized.Normalize( wxPATH_NORM_ALL );
return normalized.ToString();
}
// Pass me TRUE if the default path is to be used, and the DirPcikerCtrl disabled from use.
void Panels::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
{
m_pickerCtrl->Enable( !someNoteworthyBoolean );
if( someNoteworthyBoolean )
{
wxDirName normalized( PathDefs::Get( m_FolderId ) );
normalized.Normalize( wxPATH_NORM_ALL );
m_pickerCtrl->SetPath( normalized.ToString() );
wxFileDirPickerEvent event( m_pickerCtrl->GetEventType(), m_pickerCtrl, m_pickerCtrl->GetId(), normalized.ToString() );
m_pickerCtrl->GetEventHandler()->ProcessEvent(event);
}
}
void Panels::DirPickerPanel::UseDefaultPath_Click( wxCommandEvent &event )
{
wxASSERT( m_pickerCtrl != NULL && m_checkCtrl != NULL );
UpdateCheckStatus( m_checkCtrl->IsChecked() );
}
void Panels::DirPickerPanel::Explore_Click( wxCommandEvent &event )
{
wxHelpers::Explore( m_pickerCtrl->GetPath() );
}
// ------------------------------------------------------------------------
// If initPath is NULL, then it's assumed the default folder is to be used, which is
// obtained from invoking the specified getDefault() function.
//
Panels::DirPickerPanel::DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel ) :
BaseApplicableConfigPanel( parent, wxDefaultCoord )
, m_FolderId( folderid )
, m_pickerCtrl( NULL )
, m_checkCtrl( NULL )
{
wxStaticBoxSizer& s_box( *new wxStaticBoxSizer( wxVERTICAL, this, label ) );
wxFlexGridSizer& s_lower( *new wxFlexGridSizer( 2, 0, 4 ) );
s_lower.AddGrowableCol( 1 );
// Force the Dir Picker to use a text control. This isn't standard on Linux/GTK but it's much
// more usable, so to hell with standards.
wxString normalized( GetNormalizedConfigFolder( m_FolderId ) );
if( wxFile::Exists( normalized ) )
{
// The default path is invalid... What should we do here? hmm..
}
if( !wxDir::Exists( normalized ) )
wxMkdir( normalized );
m_pickerCtrl = new wxDirPickerCtrl( this, wxID_ANY, normalized, dialogLabel,
wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL | wxDIRP_DIR_MUST_EXIST
);
s_box.Add( m_pickerCtrl, wxSizerFlags().Border(wxLEFT | wxRIGHT | wxTOP, 5).Expand() );
m_checkCtrl = &AddCheckBox( s_lower, _("Use default setting") );
m_checkCtrl->SetToolTip( pxE( ".Tooltip:DirPicker:UseDefault",
L"When checked this folder will automatically reflect the default associated with PCSX2's current usermode setting. "
L"" )
);
wxButton* b_explore( new wxButton( this, wxID_ANY, _("Open in Explorer") ) );
b_explore->SetToolTip( _("Open an explorer window to this folder.") );
s_lower.Add( b_explore, SizerFlags::StdButton().Align( wxALIGN_RIGHT ) );
s_box.Add( &s_lower, wxSizerFlags().Expand() );
SetSizerAndFit( &s_box );
// Apply default values
const bool isDefault = g_Conf->Folders.IsDefault( m_FolderId );
m_checkCtrl->SetValue( isDefault );
m_pickerCtrl->Enable( !isDefault );
Connect( m_checkCtrl->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DirPickerPanel::UseDefaultPath_Click ) );
Connect( b_explore->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DirPickerPanel::Explore_Click ) );
}
Panels::DirPickerPanel& Panels::DirPickerPanel::SetStaticDesc( const wxString& msg )
{
InsertStaticTextAt( this, *GetSizer(), 0, msg );
SetSizerAndFit( GetSizer(), false );
return *this;
}
void Panels::DirPickerPanel::Reset()
{
m_pickerCtrl->SetPath( GetNormalizedConfigFolder( m_FolderId ) );
}
void Panels::DirPickerPanel::Apply( AppConfig& conf )
{
conf.Folders.Set( m_FolderId, m_pickerCtrl->GetPath(), m_checkCtrl->GetValue() );
}

View File

@ -58,7 +58,7 @@ void Panels::StaticApplyState::StartWizard()
// Returns false if one of the panels fails input validation (in which case dialogs // Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc). // should not be closed, etc).
// //
bool Panels::StaticApplyState::ApplyPage( int pageid ) bool Panels::StaticApplyState::ApplyPage( int pageid, bool saveOnSuccess )
{ {
bool retval = true; bool retval = true;
try try
@ -82,7 +82,8 @@ bool Panels::StaticApplyState::ApplyPage( int pageid )
*g_Conf = confcopy; *g_Conf = confcopy;
UseAdminMode = g_ApplyState.UseAdminMode; UseAdminMode = g_ApplyState.UseAdminMode;
g_Conf->Apply(); g_Conf->Apply();
g_Conf->Save(); if( saveOnSuccess )
g_Conf->Save();
} }
catch( Exception::CannotApplySettings& ex ) catch( Exception::CannotApplySettings& ex )
{ {

View File

@ -19,78 +19,11 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "ConfigurationPanels.h" #include "ConfigurationPanels.h"
#include <wx/notebook.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
using namespace wxHelpers; using namespace wxHelpers;
static const int BetweenFolderSpace = 5; static const int BetweenFolderSpace = 5;
static wxString GetNormalizedConfigFolder( FoldersEnum_t folderId )
{
const bool isDefault = g_Conf->Folders.IsDefault( folderId );
wxDirName normalized( isDefault ? g_Conf->Folders[folderId] : PathDefs::Get(folderId) );
normalized.Normalize( wxPATH_NORM_ALL );
return normalized.ToString();
}
// Pass me TRUE if the default path is to be used, and the DirPcikerCtrl disabled from use.
void Panels::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
{
m_pickerCtrl->Enable( !someNoteworthyBoolean );
if( someNoteworthyBoolean )
{
wxDirName normalized( PathDefs::Get( m_FolderId ) );
normalized.Normalize( wxPATH_NORM_ALL );
m_pickerCtrl->SetPath( normalized.ToString() );
}
}
void Panels::DirPickerPanel::UseDefaultPath_Click(wxCommandEvent &event)
{
wxASSERT( m_pickerCtrl != NULL && m_checkCtrl != NULL );
UpdateCheckStatus( m_checkCtrl->IsChecked() );
}
// ------------------------------------------------------------------------
// If initPath is NULL, then it's assumed the default folder is to be used, which is
// obtained from invoking the specified getDefault() function.
//
Panels::DirPickerPanel::DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid,
const wxString& label, const wxString& dialogLabel ) :
BaseApplicableConfigPanel( parent, wxDefaultCoord )
, m_FolderId( folderid )
{
wxStaticBoxSizer& s_box = *new wxStaticBoxSizer( wxVERTICAL, this, label );
// Force the Dir Picker to use a text control. This isn't standard on Linux/GTK but it's much
// more usable, so to hell with standards.
m_pickerCtrl = new wxDirPickerCtrl( this, wxID_ANY, GetNormalizedConfigFolder( m_FolderId ), dialogLabel,
wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL | wxDIRP_DIR_MUST_EXIST
);
s_box.Add( m_pickerCtrl, wxSizerFlags().Border(wxLEFT | wxRIGHT | wxTOP, 5).Expand() );
m_checkCtrl = &AddCheckBox( s_box, _("Use installation default setting") );
const bool isDefault = g_Conf->Folders.IsDefault( m_FolderId );
m_checkCtrl->SetValue( isDefault );
UpdateCheckStatus( isDefault );
SetSizerAndFit( &s_box );
Connect( m_checkCtrl->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DirPickerPanel::UseDefaultPath_Click ) );
}
void Panels::DirPickerPanel::Reset()
{
m_pickerCtrl->SetPath( GetNormalizedConfigFolder( m_FolderId ) );
}
void Panels::DirPickerPanel::Apply( AppConfig& conf )
{
conf.Folders.Set( m_FolderId, m_pickerCtrl->GetPath(), m_checkCtrl->GetValue() );
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
Panels::BasePathsPanel::BasePathsPanel( wxWindow& parent, int idealWidth ) : Panels::BasePathsPanel::BasePathsPanel( wxWindow& parent, int idealWidth ) :
wxPanelWithHelpers( &parent, idealWidth-12 ) wxPanelWithHelpers( &parent, idealWidth-12 )
@ -110,16 +43,6 @@ Panels::DirPickerPanel& Panels::BasePathsPanel::AddDirPicker( wxBoxSizer& sizer,
Panels::StandardPathsPanel::StandardPathsPanel( wxWindow& parent ) : Panels::StandardPathsPanel::StandardPathsPanel( wxWindow& parent ) :
BasePathsPanel( parent ) BasePathsPanel( parent )
{ {
// TODO : Replace the callback mess here with the new FolderId enumeration setup. :)
AddDirPicker( s_main, FolderId_Bios,
_("Bios:"),
_("Select folder with PS2 Bios") ).
SetToolTip( pxE( ".Tooltips:Folders:Bios",
L"This folder is where PCSX2 looks to find PS2 bios files. The actual bios used can be "
L"selected from the CPU dialog."
) );
s_main.AddSpacer( BetweenFolderSpace ); s_main.AddSpacer( BetweenFolderSpace );
AddDirPicker( s_main, FolderId_Savestates, AddDirPicker( s_main, FolderId_Savestates,
_("Savestates:"), _("Savestates:"),
@ -160,78 +83,3 @@ Panels::StandardPathsPanel::StandardPathsPanel( wxWindow& parent ) :
SetSizerAndFit( &s_main ); SetSizerAndFit( &s_main );
} }
// ------------------------------------------------------------------------
Panels::AdvancedPathsPanel::AdvancedPathsPanel( wxWindow& parent, int idealWidth ) :
BasePathsPanel( parent, idealWidth-9 )
, m_dirpick_plugins(
AddDirPicker( s_main, FolderId_Plugins,
_("Plugins folder:"),
_("Select a PCSX2 plugins folder")
)
)
, m_dirpick_settings( (
s_main.AddSpacer( BetweenFolderSpace ),
AddDirPicker( s_main, FolderId_Settings,
_("Settings folder:"),
_("Select location to save PCSX2 settings to")
)
) )
{
m_dirpick_plugins.SetToolTip( pxE( ".Tooltips:Folders:Plugins",
L"This is the location where PCSX2 will expect to find its plugins. Plugins found in this folder "
L"will be enumerated and are selectable from the Plugins panel."
) );
m_dirpick_settings.SetToolTip( pxE( ".Tooltips:Folders:Settings",
L"This is the folder where PCSX2 saves all settings, including settings generated "
L"by most plugins.\n\nWarning: Some older versions of plugins may not respect this value."
) );
SetSizerAndFit( &s_main );
}
void Panels::AdvancedPathsPanel::Reset()
{
m_dirpick_plugins.Reset();
m_dirpick_settings.Reset();
}
// ------------------------------------------------------------------------
Panels::TabbedPathsPanel::TabbedPathsPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth )
{
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
wxNotebook& notebook = *new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM | wxNB_FIXEDWIDTH );
StandardPathsPanel& stah( *new StandardPathsPanel( notebook ) );
AdvancedPathsPanel& apah( *new AdvancedPathsPanel( notebook, GetIdealWidth() ) );
notebook.AddPage( &stah, _("Standard") );
notebook.AddPage( &apah, _("Advanced") );
// Advanced Tab uses the Advanced Panel with some extra features.
// This is because the extra features are not present on the Wizard version of the Advanced Panel.
wxStaticBoxSizer& advanced = *new wxStaticBoxSizer( wxVERTICAL, this, _("Advanced") );
AddStaticText( advanced, pxE( ".Panels:Folders:Advanced",
L"Warning!! These advanced options are provided for developers and advanced testers only. "
L"Changing these settings can cause program errors and may require administration privlidges, "
L"so please be weary."
) );
advanced.Add( new UsermodeSelectionPanel( *this, GetIdealWidth()-9 ), SizerFlags::SubGroup() );
advanced.AddSpacer( 4 );
advanced.Add( &apah.Sizer(), SizerFlags::SubGroup() );
apah.SetSizer( &advanced, false );
apah.Fit();
s_main.Add( &notebook, SizerFlags::StdSpace() );
SetSizerAndFit( &s_main );
}
void Panels::TabbedPathsPanel::Apply( AppConfig& conf )
{
}

View File

@ -17,10 +17,10 @@
*/ */
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Utilities/ScopedPtr.h" #include "System.h"
#include "Plugins.h" #include "Plugins.h"
#include "Utilities/ScopedPtr.h"
#include "ConfigurationPanels.h" #include "ConfigurationPanels.h"
#include "ps2/BiosTools.h"
#include <wx/dynlib.h> #include <wx/dynlib.h>
#include <wx/dir.h> #include <wx/dir.h>
@ -28,8 +28,10 @@
using namespace wxHelpers; using namespace wxHelpers;
using namespace Threading; using namespace Threading;
DECLARE_EVENT_TYPE(wxEVT_EnumeratedNext, -1) BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(wxEVT_EnumerationFinished, -1) DECLARE_EVENT_TYPE(wxEVT_EnumeratedNext, -1)
DECLARE_EVENT_TYPE(wxEVT_EnumerationFinished, -1)
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE(wxEVT_EnumeratedNext) DEFINE_EVENT_TYPE(wxEVT_EnumeratedNext)
DEFINE_EVENT_TYPE(wxEVT_EnumerationFinished); DEFINE_EVENT_TYPE(wxEVT_EnumerationFinished);
@ -65,6 +67,7 @@ public:
if( !m_plugin.Load( m_plugpath ) ) if( !m_plugin.Load( m_plugpath ) )
throw Exception::BadStream( m_plugpath, "File is not a valid dynamic library" ); throw Exception::BadStream( m_plugpath, "File is not a valid dynamic library" );
wxDoNotLogInThisScope please;
m_GetLibType = (_PS2EgetLibType)m_plugin.GetSymbol( L"PS2EgetLibType" ); m_GetLibType = (_PS2EgetLibType)m_plugin.GetSymbol( L"PS2EgetLibType" );
m_GetLibName = (_PS2EgetLibName)m_plugin.GetSymbol( L"PS2EgetLibName" ); m_GetLibName = (_PS2EgetLibName)m_plugin.GetSymbol( L"PS2EgetLibName" );
m_GetLibVersion2 = (_PS2EgetLibVersion2)m_plugin.GetSymbol( L"PS2EgetLibVersion2" ); m_GetLibVersion2 = (_PS2EgetLibVersion2)m_plugin.GetSymbol( L"PS2EgetLibVersion2" );
@ -153,11 +156,13 @@ void Panels::PluginSelectorPanel::StatusPanel::Reset()
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
Panels::PluginSelectorPanel::ComboBoxPanel::ComboBoxPanel( PluginSelectorPanel* parent ) : Panels::PluginSelectorPanel::ComboBoxPanel::ComboBoxPanel( PluginSelectorPanel* parent ) :
wxPanelWithHelpers( parent ) wxPanelWithHelpers( parent )
, m_BiosBox( *new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY | wxCB_SORT ) ) , m_FolderPicker( *new DirPickerPanel( this, FolderId_Plugins,
_("Plugins Search Path:"),
_("Select a folder with PCSX2 plugins") )
)
{ {
m_BiosBox.SetFont( wxFont( m_BiosBox.GetFont().GetPointSize()+1, wxFONTFAMILY_MODERN, wxNORMAL, wxNORMAL, false, L"Lucida Console" ) ); wxBoxSizer& s_main( *new wxBoxSizer( wxVERTICAL ) );
wxFlexGridSizer& s_plugin( *new wxFlexGridSizer( NumPluginTypes, 3, 16, 10 ) );
wxFlexGridSizer& s_plugin = *new wxFlexGridSizer( NumPluginTypes, 3, 16, 10 );
s_plugin.SetFlexibleDirection( wxHORIZONTAL ); s_plugin.SetFlexibleDirection( wxHORIZONTAL );
s_plugin.AddGrowableCol( 1 ); // expands combo boxes to full width. s_plugin.AddGrowableCol( 1 ); // expands combo boxes to full width.
@ -174,10 +179,13 @@ Panels::PluginSelectorPanel::ComboBoxPanel::ComboBoxPanel( PluginSelectorPanel*
s_plugin.Add( new wxButton( this, wxID_ANY, L"Configure..." ) ); s_plugin.Add( new wxButton( this, wxID_ANY, L"Configure..." ) );
} }
s_plugin.Add( new wxStaticText( this, wxID_ANY, L"BIOS" ), wxSizerFlags().Border( wxTOP | wxLEFT, 2 ) ); m_FolderPicker.SetStaticDesc( _("Click the Browse button to select a different folder for PCSX2 plugins.") );
s_plugin.Add( &m_BiosBox, wxSizerFlags().Expand() );
SetSizerAndFit( &s_plugin ); s_main.Add( &s_plugin, wxSizerFlags().Expand() );
s_main.AddSpacer( 6 );
s_main.Add( &m_FolderPicker, SizerFlags::StdExpand() );
SetSizerAndFit( &s_main );
} }
void Panels::PluginSelectorPanel::ComboBoxPanel::Reset() void Panels::PluginSelectorPanel::ComboBoxPanel::Reset()
@ -188,23 +196,20 @@ void Panels::PluginSelectorPanel::ComboBoxPanel::Reset()
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWidth ) : Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth ) BaseSelectorPanel( parent, idealWidth )
, m_FileList( NULL ) , m_FileList( NULL )
, m_BiosList( NULL )
, m_StatusPanel( *new StatusPanel( this ) ) , m_StatusPanel( *new StatusPanel( this ) )
, m_ComponentBoxes( *new ComboBoxPanel( this ) ) , m_ComponentBoxes( *new ComboBoxPanel( this ) )
, m_EnumeratorThread( NULL ) , m_EnumeratorThread( NULL )
{ {
//ValidateEnumerationStatus(); // note: the status panel is a floating window, so that it can be positioned in the
// center of the dialog after it's been fitted to the contents.
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
wxBoxSizer& s_main( *new wxBoxSizer( wxVERTICAL ) );
s_main.Add( &m_ComponentBoxes, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() ); s_main.Add( &m_ComponentBoxes, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() );
//s_main.AddSpacer( 4 ); m_StatusPanel.Hide();
//AddStaticText( s_main, _("Tip: Installed plugins that are not compatible with your hardware or operating system will be listed below a separator.") ); m_ComponentBoxes.Hide();
s_main.AddSpacer( 4 );
s_main.Add( &m_StatusPanel, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() );
// refresh button used for diagnostics... (don't think there's a point to having one otherwise) --air // refresh button used for diagnostics... (don't think there's a point to having one otherwise) --air
//wxButton* refresh = new wxButton( this, wxID_ANY, L"Refresh" ); //wxButton* refresh = new wxButton( this, wxID_ANY, L"Refresh" );
@ -213,22 +218,13 @@ Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWid
SetSizerAndFit( &s_main ); SetSizerAndFit( &s_main );
Connect( GetId(), wxEVT_SHOW, wxShowEventHandler( PluginSelectorPanel::OnShow ) );
Connect( wxEVT_EnumeratedNext, wxCommandEventHandler( PluginSelectorPanel::OnProgress ) ); Connect( wxEVT_EnumeratedNext, wxCommandEventHandler( PluginSelectorPanel::OnProgress ) );
Connect( wxEVT_EnumerationFinished, wxCommandEventHandler( PluginSelectorPanel::OnEnumComplete ) ); Connect( wxEVT_EnumerationFinished, wxCommandEventHandler( PluginSelectorPanel::OnEnumComplete ) );
} }
Panels::PluginSelectorPanel::~PluginSelectorPanel() Panels::PluginSelectorPanel::~PluginSelectorPanel()
{ {
// Random crashes on null function pointer if we don't clean up the event... CancelRefresh(); // in case the enumeration thread is currently refreshing...
Disconnect( GetId(), wxEVT_SHOW, wxShowEventHandler( PluginSelectorPanel::OnShow ) );
// Kill the thread if it's alive.
safe_delete( m_EnumeratorThread );
safe_delete( m_FileList );
safe_delete( m_BiosList );
} }
void Panels::PluginSelectorPanel::Apply( AppConfig& conf ) void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
@ -255,27 +251,15 @@ void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
} }
wxFileName relative( GetFilename((int)m_ComponentBoxes.Get(i).GetClientData(sel)) ); wxFileName relative( GetFilename((int)m_ComponentBoxes.Get(i).GetClientData(sel)) );
relative.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() ); relative.MakeRelativeTo( conf.Folders.Plugins.ToString() );
conf.BaseFilenames.Plugins[tbl_PluginInfo[i].id] = relative.GetFullPath(); conf.BaseFilenames.Plugins[tbl_PluginInfo[i].id] = relative.GetFullPath();
} }
}
int sel = m_ComponentBoxes.GetBios().GetSelection();
if( sel == wxNOT_FOUND )
{
throw Exception::CannotApplySettings( this,
// English Log
L"User did not specify a valid BIOS selection.",
// Translated void Panels::PluginSelectorPanel::CancelRefresh()
pxE( ".Popup Error:Invalid BIOS Selection", {
L"Please select a valid BIOS before applying new settings. If you are unable to make\n" safe_delete( m_EnumeratorThread );
L"a valid selection then press cancel to close the Configuration panel." safe_delete( m_FileList );
)
);
}
wxFileName relative( (*m_BiosList)[(int)m_ComponentBoxes.GetBios().GetClientData(sel)] );
relative.MakeRelativeTo( g_Conf->Folders.Bios.ToString() );
conf.BaseFilenames.Bios = relative.GetFullPath();
} }
void Panels::PluginSelectorPanel::DoRefresh() void Panels::PluginSelectorPanel::DoRefresh()
@ -283,6 +267,9 @@ void Panels::PluginSelectorPanel::DoRefresh()
// Disable all controls until enumeration is complete. // Disable all controls until enumeration is complete.
m_ComponentBoxes.Hide(); m_ComponentBoxes.Hide();
m_StatusPanel.SetSize( m_ComponentBoxes.GetSize().GetWidth() - 8, wxDefaultCoord );
//m_StatusPanel.SetSizer( m_StatusPanel.GetSizer(), false );
m_StatusPanel.CentreOnParent();
m_StatusPanel.Show(); m_StatusPanel.Show();
// Use a thread to load plugins. // Use a thread to load plugins.
@ -297,29 +284,20 @@ bool Panels::PluginSelectorPanel::ValidateEnumerationStatus()
{ {
bool validated = true; bool validated = true;
// re-enumerate plugins and bioses, and if anything changed then we need to wipe // re-enumerate plugins, and if anything changed then we need to wipe
// the contents of the combo boxes and re-enumerate everything. // the contents of the combo boxes and re-enumerate everything.
// Impl Note: ScopedPtr used so that resources get cleaned up if an exception // Impl Note: ScopedPtr used so that resources get cleaned up if an exception
// occurs during file enumeration. // occurs during file enumeration.
wxScopedPtr<wxArrayString> pluginlist( new wxArrayString() ); wxScopedPtr<wxArrayString> pluginlist( new wxArrayString() );
wxScopedPtr<wxArrayString> bioslist( new wxArrayString() );
int pluggers = EnumeratePluginsFolder( pluginlist.get() ); int pluggers = EnumeratePluginsInFolder( m_ComponentBoxes.GetPluginsPath(), pluginlist.get() );
if( g_Conf->Folders.Bios.Exists() )
wxDir::GetAllFiles( g_Conf->Folders.Bios.ToString(), bioslist.get(), L"*.bin", wxDIR_FILES );
if( (m_FileList == NULL) || (*pluginlist != *m_FileList) ) if( (m_FileList == NULL) || (*pluginlist != *m_FileList) )
validated = false; validated = false;
if( (m_BiosList == NULL) || (*bioslist != *m_BiosList) )
validated = false;
delete m_FileList; delete m_FileList;
delete m_BiosList;
m_FileList = pluginlist.release(); m_FileList = pluginlist.release();
m_BiosList = bioslist.release();
m_StatusPanel.SetGaugeLength( pluggers ); m_StatusPanel.SetGaugeLength( pluggers );
@ -327,53 +305,10 @@ bool Panels::PluginSelectorPanel::ValidateEnumerationStatus()
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// This overload of OnShow is invoked by wizards, since the wxWizard won't raise
// SHOW events. >_< (only called for show events and not hide events)
void Panels::PluginSelectorPanel::OnShow()
{
if( !ValidateEnumerationStatus() )
DoRefresh();
}
void Panels::PluginSelectorPanel::OnShow( wxShowEvent& evt )
{
evt.Skip();
if( !evt.GetShow() ) return;
OnShow();
}
void Panels::PluginSelectorPanel::OnRefresh( wxCommandEvent& evt )
{
ValidateEnumerationStatus();
DoRefresh();
}
void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt ) void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
{ {
safe_delete( m_EnumeratorThread ); safe_delete( m_EnumeratorThread );
// -----------------
// Enumerate BIOS
// -----------------
wxFileName right( g_Conf->FullpathToBios() );
right.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
for( size_t i=0; i<m_BiosList->GetCount(); ++i )
{
wxString description;
if( !IsBIOS((*m_BiosList)[i], description) ) continue;
int sel = m_ComponentBoxes.GetBios().Append( description, (void*)i );
wxFileName left( (*m_BiosList)[i] );
left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
if( left == right )
m_ComponentBoxes.GetBios().SetSelection( sel );
}
// fixme: Default plugins should be picked based on the timestamp of the DLL or something? // fixme: Default plugins should be picked based on the timestamp of the DLL or something?
// (for now we just force it to selection zero if nothing's selected) // (for now we just force it to selection zero if nothing's selected)
@ -387,14 +322,13 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
m_ComponentBoxes.Get(i).SetSelection( 0 ); m_ComponentBoxes.Get(i).SetSelection( 0 );
} }
if( emptyBoxes > 0 ) /*if( emptyBoxes > 0 )
{ {
wxMessageBox( pxE( ".Popup Error:Missing Plugins", Msgbox::Alert( pxE( ".Popup Error:Missing Plugins",
L"Critical Error: A valid plugin for one or more components of PCSX2 could not be found. " L"Critical Error: A valid plugin for one or more components of PCSX2 could not be found.\n"
L"Your installation of PCSX2 is incomplete, and will be unable to run games."), L"If this is a fresh install of PCSX2 then your installation may be corrupted or incomplete.\n")
_("PCSX2 Error - Plugin components not found")
); );
} }*/
m_ComponentBoxes.Show(); m_ComponentBoxes.Show();
m_StatusPanel.Hide(); m_StatusPanel.Hide();
@ -454,21 +388,25 @@ Panels::PluginSelectorPanel::EnumThread::EnumThread( PluginSelectorPanel& master
Panels::PluginSelectorPanel::EnumThread::~EnumThread() Panels::PluginSelectorPanel::EnumThread::~EnumThread()
{ {
safe_delete_array( Results );
Cancel(); Cancel();
safe_delete_array( Results );
} }
void Panels::PluginSelectorPanel::EnumThread::Cancel() void Panels::PluginSelectorPanel::EnumThread::Cancel()
{ {
m_cancel = true; m_cancel = true;
Threading::Sleep( 1 ); Sleep( 2 );
PersistentThread::Cancel(); PersistentThread::Cancel();
} }
sptr Panels::PluginSelectorPanel::EnumThread::ExecuteTask() sptr Panels::PluginSelectorPanel::EnumThread::ExecuteTask()
{ {
for( int curidx=0; curidx < m_master.FileCount() && !m_cancel; ++curidx ) Sleep( 10 ); // gives the gui thread some time to refresh
for( int curidx=0; curidx < m_master.FileCount(); ++curidx )
{ {
if( m_cancel ) return 0;
try try
{ {
PluginEnumerator penum( m_master.GetFilename( curidx ) ); PluginEnumerator penum( m_master.GetFilename( curidx ) );
@ -494,6 +432,8 @@ sptr Panels::PluginSelectorPanel::EnumThread::ExecuteTask()
Console::Status( ex.LogMessage() ); Console::Status( ex.LogMessage() );
} }
pthread_testcancel();
wxCommandEvent yay( wxEVT_EnumeratedNext ); wxCommandEvent yay( wxEVT_EnumeratedNext );
yay.SetExtraLong( curidx ); yay.SetExtraLong( curidx );
m_master.GetEventHandler()->AddPendingEvent( yay ); m_master.GetEventHandler()->AddPendingEvent( yay );

View File

@ -86,14 +86,13 @@ static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs )
// //
void i18n_EnumeratePackages( LangPackList& langs ) void i18n_EnumeratePackages( LangPackList& langs )
{ {
bool prev = wxLog::EnableLogging( false ); // wx generates verbose errors if languages don't exist, so disable them here. wxDoNotLogInThisScope here; // wx generates verbose errors if languages don't exist, so disable them here.
langs.push_back( LangPackEnumeration() ); langs.push_back( LangPackEnumeration() );
for( int li=wxLANGUAGE_UNKNOWN+1; li<wxLANGUAGE_USER_DEFINED; ++li ) for( int li=wxLANGUAGE_UNKNOWN+1; li<wxLANGUAGE_USER_DEFINED; ++li )
{ {
i18n_DoPackageCheck( (wxLanguage)li, langs ); i18n_DoPackageCheck( (wxLanguage)li, langs );
} }
wxLog::EnableLogging( prev );
// Brilliant. Because someone in the wx world didn't think to move wxLANGUAGE_USER_DEFINED // Brilliant. Because someone in the wx world didn't think to move wxLANGUAGE_USER_DEFINED
// to a place where it wasn't butt right up against the main languages (like, say, start user // to a place where it wasn't butt right up against the main languages (like, say, start user

View File

@ -177,13 +177,24 @@ namespace wxHelpers
{ {
// No reason to ever have AutoResize enabled, quite frankly. It just causes layout and centering problems. // No reason to ever have AutoResize enabled, quite frankly. It just causes layout and centering problems.
alignFlags |= wxST_NO_AUTORESIZE; alignFlags |= wxST_NO_AUTORESIZE;
wxStaticText *temp = new wxStaticText(parent, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, alignFlags ); wxStaticText& temp( *new wxStaticText(parent, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, alignFlags ) );
if( size > 0 ) temp->Wrap( size ); if( size > 0 ) temp.Wrap( size );
sizer.Add(temp, SizerFlags::StdSpace().Align( alignFlags & wxALIGN_MASK ) ); sizer.Add( &temp, SizerFlags::StdSpace().Align( alignFlags & wxALIGN_MASK ) );
return *temp; return temp;
} }
wxStaticText& InsertStaticTextAt(wxWindow* parent, wxSizer& sizer, int position, const wxString& label, int alignFlags, int size )
{
// No reason to ever have AutoResize enabled, quite frankly. It just causes layout and centering problems.
alignFlags |= wxST_NO_AUTORESIZE;
wxStaticText& temp( *new wxStaticText(parent, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, alignFlags ) );
if( size > 0 ) temp.Wrap( size );
sizer.Insert( position, &temp, SizerFlags::StdSpace().Align( alignFlags & wxALIGN_MASK ) );
return temp;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Launches the specified file according to its mime type // Launches the specified file according to its mime type
// //

View File

@ -1,13 +1,41 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once #pragma once
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/filepicker.h> #include <wx/filepicker.h>
#include "Utilities/wxGuiTools.h"
namespace wxHelpers namespace wxHelpers
{ {
extern wxCheckBox& AddCheckBoxTo( wxWindow* parent, wxSizer& sizer, const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString, int wrapLen=wxDefaultCoord ); extern wxCheckBox& AddCheckBoxTo( wxWindow* parent, wxSizer& sizer, const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString, int wrapLen=wxDefaultCoord );
extern wxRadioButton& AddRadioButtonTo( wxWindow* parent, wxSizer& sizer, const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString, int wrapLen=wxDefaultCoord, bool isFirst = false ); extern wxRadioButton& AddRadioButtonTo( wxWindow* parent, wxSizer& sizer, const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString, int wrapLen=wxDefaultCoord, bool isFirst = false );
extern wxStaticText& AddStaticTextTo(wxWindow* parent, wxSizer& sizer, const wxString& label, int alignFlags=wxALIGN_CENTRE, int wrapLen=wxDefaultCoord ); extern wxStaticText& AddStaticTextTo(wxWindow* parent, wxSizer& sizer, const wxString& label, int alignFlags=wxALIGN_CENTRE, int wrapLen=wxDefaultCoord );
extern wxStaticText& InsertStaticTextAt(wxWindow* parent, wxSizer& sizer, int position, const wxString& label, int alignFlags=wxALIGN_CENTRE, int wrapLen=wxDefaultCoord );
extern void Explore( const wxString& path );
extern void Explore( const char *path );
extern void Launch( const wxString& path );
extern void Launch( const char *path );
namespace SizerFlags namespace SizerFlags
{ {
@ -21,101 +49,6 @@ namespace wxHelpers
}; };
} }
//////////////////////////////////////////////////////////////////////////////////////////
// pxTextWrapper
// this class is used to wrap the text on word boundary: wrapping is done by calling
// OnStartLine() and OnOutputLine() functions. This class by itself can be used as a
// line counting tool, but produces no formatted text output.
//
// [class "borrowed" from wxWidgets private code, and renamed to avoid possible conflicts
// with future editions of wxWidgets which might make it public. Why this isn't publicly
// available already in wxBase I'll never know-- air]
//
class pxTextWrapperBase
{
protected:
bool m_eol;
int m_linecount;
public:
virtual ~pxTextWrapperBase() { }
pxTextWrapperBase() :
m_eol( false )
, m_linecount( 0 )
{
}
// win is used for getting the font, text is the text to wrap, width is the
// max line width or -1 to disable wrapping
void Wrap( const wxWindow *win, const wxString& text, int widthMax );
int GetLineCount() const
{
return m_linecount;
}
protected:
// line may be empty
virtual void OnOutputLine(const wxString& line) { }
// called at the start of every new line (except the very first one)
virtual void OnNewLine() { }
void DoOutputLine(const wxString& line)
{
OnOutputLine(line);
m_linecount++;
m_eol = true;
}
// this function is a destructive inspector: when it returns true it also
// resets the flag to false so calling it again wouldn't return true any
// more
bool IsStartOfNewLine()
{
if ( !m_eol )
return false;
m_eol = false;
return true;
}
};
//////////////////////////////////////////////////////////////////////////////////////////
// pxTextWrapper
// This class extends pxTextWrapperBase and adds the ability to retrieve the formatted
// result of word wrapping.
//
class pxTextWrapper : public pxTextWrapperBase
{
protected:
wxString m_text;
public:
pxTextWrapper() : pxTextWrapperBase()
, m_text()
{
}
const wxString& GetResult() const
{
return m_text;
}
protected:
virtual void OnOutputLine(const wxString& line)
{
m_text += line;
}
virtual void OnNewLine()
{
m_text += L'\n';
}
};
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
class wxDialogWithHelpers : public wxDialog class wxDialogWithHelpers : public wxDialog

View File

@ -1993,6 +1993,10 @@
RelativePath="..\..\gui\Dialogs\FirstTimeWizard.cpp" RelativePath="..\..\gui\Dialogs\FirstTimeWizard.cpp"
> >
</File> </File>
<File
RelativePath="..\..\gui\Dialogs\ImportSettingsDialog.cpp"
>
</File>
<File <File
RelativePath="..\..\gui\Dialogs\LogOptionsDialog.cpp" RelativePath="..\..\gui\Dialogs\LogOptionsDialog.cpp"
> >
@ -2069,6 +2073,10 @@
RelativePath="..\..\gui\Panels\AudioPanel.cpp" RelativePath="..\..\gui\Panels\AudioPanel.cpp"
> >
</File> </File>
<File
RelativePath="..\..\gui\Panels\BiosSelectorPanel.cpp"
>
</File>
<File <File
RelativePath="..\..\gui\Panels\ConfigurationPanels.h" RelativePath="..\..\gui\Panels\ConfigurationPanels.h"
> >
@ -2077,6 +2085,10 @@
RelativePath="..\..\gui\Panels\CpuPanel.cpp" RelativePath="..\..\gui\Panels\CpuPanel.cpp"
> >
</File> </File>
<File
RelativePath="..\..\gui\Panels\DirPickerPanel.cpp"
>
</File>
<File <File
RelativePath="..\..\gui\Panels\GameFixesPanel.cpp" RelativePath="..\..\gui\Panels\GameFixesPanel.cpp"
> >