Major Settings Changes!

* PCSX2 now splits settings into two files: pcsx2-ui.ini and pcsx2-vm.ini.  The former is user interface clutter (window positions, confirmation dialogs, etc).  The latter is virtual machine settings, speed hacks, game fixes, etc.
 * Added support for PORTABLE INSTALLS!!  Portable install is currently manually enabled by adding an empty "pcsx2-portable.ini" to the install location of PCSX2.  Portable installs should run seamlessly from any flash drive, etc. (and will usually need Admin rights)
 * PCSX2 install location and plugins folders are stored in the registry now (unless portable install is enabled, in which case no registry is used).

Notes:
 * A button to enable portable installs from within PCSX2 is planned.
 * NSIS installer will hopefully be upgraded to allow for a portable install option as well.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4198 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2011-01-10 17:48:25 +00:00
parent 90eda53e42
commit df6f1b03f7
20 changed files with 725 additions and 275 deletions

View File

@ -20,8 +20,9 @@
#define g_MaxPath 255 // 255 is safer with antiquated Win32 ASCII APIs.
//////////////////////////////////////////////////////////////////////////////////////////
//
// --------------------------------------------------------------------------------------
// wxDirName
// --------------------------------------------------------------------------------------
class wxDirName : protected wxFileName
{
public:
@ -103,6 +104,7 @@ public:
wxFileName operator+( const wxFileName& right ) const { return Combine( right ); }
wxDirName operator+( const wxDirName& right ) const { return Combine( right ); }
wxFileName operator+( const wxString& right ) const { return Combine( wxFileName(right) ); }
wxFileName operator+( const char* right ) const { return Combine( wxFileName(fromUTF8(right)) ); }
bool operator==(const wxDirName& filename) const { return SameAs(filename); }
bool operator!=(const wxDirName& filename) const { return !SameAs(filename); }

View File

@ -77,6 +77,11 @@ public:
return m_ptr;
}
// Swaps two pointers between likened scoped pointer types. This method is useful for
// situations where you need to create a new object with a complex initializer that can
// throw exceptions -- and thusly should be disposed if the initialization fails. Use
// SwapPtr to assign the new object into the persistent ScopedPtr instance, and have
// the old object assigned to the local-scope ScopedPtr instance.
void SwapPtr(ScopedPtr& other)
{
T * const tmp = other.m_ptr;

View File

@ -80,13 +80,9 @@ void wxDirName::Rmdir()
bool wxDirName::Mkdir()
{
// wxWidgets recurses directory creation for us.
if( Exists() ) return true;
// Recursively create child directories as needed:
wxDirName recurse( *this );
recurse.RemoveLastDir();
if( !recurse.Mkdir() ) return false;
return wxFileName::Mkdir();
}

View File

@ -71,7 +71,7 @@ InstallDir "$PROGRAMFILES\PCSX2 ${APP_VERSION}"
; Registry key to check for directory (so if you install again, it will
; overwrite the old one automatically)
InstallDirRegKey ${INSTDIR_REG_ROOT} "Software\PCSX2" "Install_Dir_${APP_VERSION}"
InstallDirRegKey ${INSTDIR_REG_ROOT} "Software\PCSX2\${APP_VERSION}" "Install_Dir"
; These defines are dependent on NSIS vars assigned above.

View File

@ -19,6 +19,7 @@
!include "SharedBase.nsh"
; Reserve features for improved performance with solid archiving.
File C:\Users\Jake\Documents\devpcsx2\trunk\nsis\SharedBase.nsh
; (uncomment if we add our own install options ini files)
;!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
;!insertmacro MUI_RESERVEFILE_LANGDLL

View File

@ -17,8 +17,13 @@
enum FoldersEnum_t
{
// FIXME : Plugins, Settings, and Themes folders are no longer part of the user-local
// ini storage. They have been moved to an app-local ini storage class (which is currently
// handled lazily via global variables)
FolderId_Plugins = 0,
FolderId_Settings,
FolderId_Themes,
FolderId_Bios,
FolderId_Snapshots,
FolderId_Savestates,
@ -30,17 +35,18 @@ enum FoldersEnum_t
FolderId_COUNT
};
//////////////////////////////////////////////////////////////////////////////////////////
// PathDefs Namespace -- contains default values for various pcsx2 path names and locations.
// --------------------------------------------------------------------------------------
// PathDefs (namespace)
// --------------------------------------------------------------------------------------
// Contains default values for various pcsx2 path names and locations.
//
// Note: The members of this namespace are intended for default value initialization only.
// Most of the time you should use the path folder assignments in g_Conf instead, since those
// Everything else should use the path folder assignments in g_Conf instead, since those
// are user-configurable.
//
namespace PathDefs
{
// complete pathnames are returned by these functions
// For 99% of all code, you should use these.
// complete pathnames are returned by these functions (may or may not be absolute)
extern wxDirName GetSnapshots();
extern wxDirName GetBios();
@ -63,12 +69,15 @@ namespace PathDefs
extern const wxDirName& Settings();
extern const wxDirName& Plugins();
extern const wxDirName& Themes();
extern const wxDirName& Logs();
extern const wxDirName& Dumps();
}
}
namespace FilenameDefs
{
extern wxFileName GetConfig();
extern wxFileName GetUiConfig();
extern wxFileName GetVmConfig();
extern wxFileName GetUsermodeConfig();
extern const wxFileName& Memcard( uint port, uint slot );
};

View File

@ -309,7 +309,7 @@ class CommandlineOverrides
public:
AppConfig::FilenameOptions Filenames;
wxDirName SettingsFolder;
wxFileName SettingsFile;
wxFileName VmSettingsFile;
bool DisableSpeedhacks;
@ -342,7 +342,7 @@ public:
bool HasSettingsOverride() const
{
return SettingsFolder.IsOk() || SettingsFile.IsOk();
return SettingsFolder.IsOk() || VmSettingsFile.IsOk();
}
bool HasPluginsOverride() const
@ -539,6 +539,8 @@ public:
void CleanupResources();
void WipeUserModeSettings();
void ReadUserModeSettings();
bool TestForPortableInstall();
bool TestUserPermissionsRights( const wxDirName& testFolder, wxString& createFailedStr, wxString& accessFailedStr );
bool HasPendingSaves() const;
void StartPendingSave();

View File

@ -107,7 +107,6 @@ namespace PathDefs
switch( mode )
{
case DocsFolder_User: return (wxDirName)Path::Combine( wxStandardPaths::Get().GetDocumentsDir(), pxGetAppName() );
//case DocsFolder_CWD: return (wxDirName)wxGetCwd();
case DocsFolder_Custom: return CustomDocumentsFolder;
jNO_DEFAULT
@ -146,16 +145,16 @@ namespace PathDefs
return AppRoot() + Base::Plugins();
}
wxDirName GetSettings()
{
return GetDocuments() + Base::Settings();
}
wxDirName GetThemes()
{
return AppRoot() + Base::Themes();
}
wxDirName GetSettings()
{
return GetDocuments() + Base::Settings();
}
wxDirName GetLogs()
{
return GetDocuments() + Base::Logs();
@ -167,6 +166,7 @@ namespace PathDefs
{
case FolderId_Plugins: return GetPlugins();
case FolderId_Settings: return GetSettings();
case FolderId_Themes: return GetThemes();
case FolderId_Bios: return GetBios();
case FolderId_Snapshots: return GetSnapshots();
case FolderId_Savestates: return GetSavestates();
@ -185,8 +185,9 @@ wxDirName& AppConfig::FolderOptions::operator[]( FoldersEnum_t folderidx )
{
switch( folderidx )
{
case FolderId_Plugins: return Plugins;
case FolderId_Plugins: return PluginsFolder;
case FolderId_Settings: return SettingsFolder;
case FolderId_Themes: return ThemesFolder;
case FolderId_Bios: return Bios;
case FolderId_Snapshots: return Snapshots;
case FolderId_Savestates: return Savestates;
@ -197,7 +198,7 @@ wxDirName& AppConfig::FolderOptions::operator[]( FoldersEnum_t folderidx )
jNO_DEFAULT
}
return Plugins; // unreachable, but suppresses warnings.
return PluginsFolder; // unreachable, but suppresses warnings.
}
const wxDirName& AppConfig::FolderOptions::operator[]( FoldersEnum_t folderidx ) const
@ -209,8 +210,9 @@ bool AppConfig::FolderOptions::IsDefault( FoldersEnum_t folderidx ) const
{
switch( folderidx )
{
case FolderId_Plugins: return UseDefaultPlugins;
case FolderId_Plugins: return UseDefaultPluginsFolder;
case FolderId_Settings: return UseDefaultSettingsFolder;
case FolderId_Themes: return UseDefaultThemesFolder;
case FolderId_Bios: return UseDefaultBios;
case FolderId_Snapshots: return UseDefaultSnapshots;
case FolderId_Savestates: return UseDefaultSavestates;
@ -229,8 +231,8 @@ void AppConfig::FolderOptions::Set( FoldersEnum_t folderidx, const wxString& src
switch( folderidx )
{
case FolderId_Plugins:
Plugins = src;
UseDefaultPlugins = useDefault;
PluginsFolder = src;
UseDefaultPluginsFolder = useDefault;
break;
case FolderId_Settings:
@ -238,6 +240,11 @@ void AppConfig::FolderOptions::Set( FoldersEnum_t folderidx, const wxString& src
UseDefaultSettingsFolder = useDefault;
break;
case FolderId_Themes:
ThemesFolder = src;
UseDefaultThemesFolder = useDefault;
break;
case FolderId_Bios:
Bios = src;
UseDefaultBios = useDefault;
@ -276,10 +283,18 @@ void AppConfig::FolderOptions::Set( FoldersEnum_t folderidx, const wxString& src
// --------------------------------------------------------------------------------------
namespace FilenameDefs
{
wxFileName GetConfig()
wxFileName GetUiConfig()
{
// TODO : ini extension on Win32 is normal. Linux ini filename default might differ
// from this? like pcsx2_conf or something ... ?
// FIXME? ini extension on Win32 is normal. Linux ini filename default might differ
// from this? like pcsx2_conf or something ... ? --air
return pxGetAppName() + L".ini";
}
wxFileName GetVmConfig()
{
// FIXME? ini extension on Win32 is normal. Linux ini filename default might differ
// from this? like pcsx2_conf or something ... ? --air
return pxGetAppName() + L".ini";
}
@ -316,7 +331,7 @@ namespace FilenameDefs
wxString AppConfig::FullpathTo( PluginsEnum_t pluginidx ) const
{
return Path::Combine( Folders.Plugins, BaseFilenames[pluginidx] );
return Path::Combine( PluginsFolder, BaseFilenames[pluginidx] );
}
// returns true if the filenames are quite absolutely the equivalent. Works for all
@ -332,7 +347,7 @@ bool AppConfig::FullpathMatchTest( PluginsEnum_t pluginId, const wxString& cmpto
wxDirName GetLogFolder()
{
return UseDefaultLogs ? PathDefs::GetLogs() : Logs;
return UseDefaultLogFolder ? PathDefs::GetLogs() : LogFolder;
}
wxDirName GetSettingsFolder()
@ -343,9 +358,15 @@ wxDirName GetSettingsFolder()
return UseDefaultSettingsFolder ? PathDefs::GetSettings() : SettingsFolder;
}
wxString GetSettingsFilename()
wxString GetVmSettingsFilename()
{
wxFileName fname( wxGetApp().Overrides.SettingsFile.IsOk() ? wxGetApp().Overrides.SettingsFile : FilenameDefs::GetConfig() );
wxFileName fname( wxGetApp().Overrides.VmSettingsFile.IsOk() ? wxGetApp().Overrides.VmSettingsFile : FilenameDefs::GetVmConfig() );
return GetSettingsFolder().Combine( fname ).GetFullPath();
}
wxString GetUiSettingsFilename()
{
wxFileName fname( FilenameDefs::GetUiConfig() );
return GetSettingsFolder().Combine( fname ).GetFullPath();
}
@ -392,48 +413,27 @@ AppConfig::AppConfig()
}
// ------------------------------------------------------------------------
void AppConfig::LoadSaveUserMode( IniInterface& ini, const wxString& cwdhash )
void App_LoadSaveInstallSettings( IniInterface& ini )
{
ScopedIniGroup path( ini, cwdhash );
// timestamping would be useful if we want to auto-purge unused entries after
// a period of time. Dunno if it's needed.
/*wxString timestamp_now( wxsFormat( L"%s %s",
wxDateTime::Now().FormatISODate().c_str(), wxDateTime::Now().FormatISOTime().c_str() )
);
ini.GetConfig().Write( L"Timestamp", timestamp_now );*/
static const wxChar* DocsFolderModeNames[] =
{
L"User",
L"Custom",
};
if( ini.IsLoading() )
{
// HACK! When I removed the CWD option, the option became the cause of bad
// crashes. This detects presence of CWD, and replaces it with a custom mode
// that points to the CWD.
//
// The ini contents are rewritten and the CWD is removed. So after 0.9.7 is released,
// this code is ok to be deleted/removed. :) --air
wxString oldmode( ini.GetConfig().Read( L"DocumentsFolderMode", L"User" ) );
if( oldmode == L"CWD")
{
ini.GetConfig().Write( L"DocumentsFolderMode", L"Custom" );
ini.GetConfig().Write( L"CustomDocumentsFolder", Path::Normalize(wxGetCwd()) );
}
}
ini.EnumEntry( L"DocumentsFolderMode", DocsFolderMode, DocsFolderModeNames, DocsFolder_User );
ini.Entry( L"UseDefaultSettingsFolder", UseDefaultSettingsFolder, true );
ini.Entry( L"CustomDocumentsFolder", CustomDocumentsFolder, (wxDirName)Path::Normalize(wxGetCwd()) );
ini.Entry( L"SettingsFolder", SettingsFolder, PathDefs::GetSettings() );
// "Install_Dir" conforms to the NSIS standard install directory key name.
// Attempt to load plugins and themes based on the Install Folder.
ini.Entry( L"Install_Dir", InstallFolder, (wxDirName)wxStandardPaths::Get().GetExecutablePath() );
ini.Entry( L"PluginsFolder", PluginsFolder, InstallFolder + PathDefs::Base::Plugins() );
ini.Entry( L"ThemesFolder", ThemesFolder, InstallFolder + PathDefs::Base::Themes() );
ini.Flush();
}
@ -508,18 +508,6 @@ void AppConfig::LoadSave( IniInterface& ini )
GSWindow .LoadSave( ini );
Framerate .LoadSave( ini );
// Load Emulation options and apply some defaults overtop saved items, which are regulated
// by the PCSX2 UI.
EmuOptions.LoadSave( ini );
if( ini.IsLoading() )
{
EmuOptions.GS.LimitScalar = Framerate.NominalScalar;
if (EnablePresets){
IsOkApplyPreset(PresetIndex);
}
}
ini.Flush();
}
@ -548,7 +536,6 @@ void AppConfig::ConsoleLogOptions::LoadSave( IniInterface& ini, const wxChar* lo
void AppConfig::FolderOptions::ApplyDefaults()
{
if( UseDefaultPlugins ) Plugins = PathDefs::GetPlugins();
if( UseDefaultBios ) Bios = PathDefs::GetBios();
if( UseDefaultSnapshots ) Snapshots = PathDefs::GetSnapshots();
if( UseDefaultSavestates ) Savestates = PathDefs::GetSavestates();
@ -558,8 +545,7 @@ void AppConfig::FolderOptions::ApplyDefaults()
// ------------------------------------------------------------------------
AppConfig::FolderOptions::FolderOptions()
: Plugins ( PathDefs::GetPlugins() )
, Bios ( PathDefs::GetBios() )
: Bios ( PathDefs::GetBios() )
, Snapshots ( PathDefs::GetSnapshots() )
, Savestates ( PathDefs::GetSavestates() )
, MemoryCards ( PathDefs::GetMemoryCards() )
@ -580,15 +566,12 @@ void AppConfig::FolderOptions::LoadSave( IniInterface& ini )
ApplyDefaults();
}
IniBitBool( UseDefaultPlugins );
IniBitBool( UseDefaultSettings );
IniBitBool( UseDefaultBios );
IniBitBool( UseDefaultSnapshots );
IniBitBool( UseDefaultSavestates );
IniBitBool( UseDefaultMemoryCards );
IniBitBool( UseDefaultLogs );
IniEntry( Plugins );
IniEntry( Bios );
IniEntry( Snapshots );
IniEntry( Savestates );
@ -602,11 +585,8 @@ void AppConfig::FolderOptions::LoadSave( IniInterface& ini )
{
ApplyDefaults();
//if( DocsFolderMode != DocsFolder_CWD )
{
for( int i=0; i<FolderId_COUNT; ++i )
operator[]( (FoldersEnum_t)i ).Normalize();
}
for( int i=0; i<FolderId_COUNT; ++i )
operator[]( (FoldersEnum_t)i ).Normalize();
}
}
@ -857,29 +837,37 @@ void RelocateLogfile()
}
// Parameters:
// overwrite - this option forces the current settings to overwrite any existing settings that might
// be saved to the configured ini/settings folder.
// overwrite - this option forces the current settings to overwrite any existing settings
// that might be saved to the configured ini/settings folder.
//
// Notes:
// The overwrite option applies to PCSX2 options only. Plugin option behavior will depend
// on the plugins.
//
void AppConfig_OnChangedSettingsFolder( bool overwrite )
{
//if( DocsFolderMode != DocsFolder_CWD )
PathDefs::GetDocuments().Mkdir();
PathDefs::GetDocuments().Mkdir();
GetSettingsFolder().Mkdir();
const wxString iniFilename( GetSettingsFilename() );
const wxString iniFilename( GetUiSettingsFilename() );
if( overwrite )
{
if( wxFileExists( iniFilename ) && !wxRemoveFile( iniFilename ) )
throw Exception::AccessDenied(iniFilename)
.SetBothMsgs(pxL("Failed to overwrite existing settings file; permission was denied."));
const wxString vmIniFilename( GetVmSettingsFilename() );
if( wxFileExists( vmIniFilename ) && !wxRemoveFile( vmIniFilename ) )
throw Exception::AccessDenied(vmIniFilename)
.SetBothMsgs(pxL("Failed to overwrite existing settings file; permission was denied."));
}
// Bind into wxConfigBase to allow wx to use our config internally, and delete whatever
// comes out (cleans up prev config, if one).
delete wxConfigBase::Set( OpenFileConfig( iniFilename ) );
GetAppConfig()->SetRecordDefaults();
GetAppConfig()->SetRecordDefaults(true);
if( !overwrite )
AppLoadSettings();
@ -978,6 +966,20 @@ void AppLoadSettings()
if( !wxFile::Exists( g_Conf->CurrentIso ) )
g_Conf->CurrentIso.clear();
// Load virtual machine options and apply some defaults overtop saved items, which
// are regulated by the PCSX2 UI.
{
ScopedPtr<wxFileConfig> vmini( OpenFileConfig( GetVmSettingsFilename() ) );
IniLoader vmloader( vmini );
g_Conf->EmuOptions.LoadSave( vmloader );
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->Framerate.NominalScalar;
if (g_Conf->EnablePresets){
g_Conf->IsOkApplyPreset(g_Conf->PresetIndex);
}
}
sApp.DispatchEvent( loader );
}
@ -1007,6 +1009,15 @@ void AppSaveSettings()
g_Conf->LoadSave( saver );
ConLog_LoadSaveSettings( saver );
SysTraceLog_LoadSaveSettings( saver );
// Save virtual machine items.
{
ScopedPtr<wxFileConfig> vmini( OpenFileConfig( GetVmSettingsFilename() ) );
IniSaver vmsaver( vmini );
g_Conf->EmuOptions.LoadSave( vmsaver );
}
sApp.DispatchEvent( saver );
}

View File

@ -21,20 +21,26 @@
enum DocsModeType
{
// uses /home/user or /cwd for the program data
// uses /home/user or /cwd for the program data. This is the default mode and is the most
// friendly to modern computing security requirements; as it isolates all file modification
// to a zone of the hard drive that has granted write permissions to the user.
DocsFolder_User,
// uses the current working directory for program data
//DocsFolder_CWD,
// uses a custom location for program data
// uses a custom location for program data. Typically the custom folder is either the
// absolute or relative location of the program -- absolute is preferred because it is
// considered more secure by MSW standards, due to DLL search rules.
//
// To enable PCSX2's "portable" mode, use this setting and specify "." for the custom
// documents folder.
DocsFolder_Custom,
};
namespace PathDefs
{
// complete pathnames are returned by these functions
// For 99% of all code, you should use these.
// complete pathnames are returned by these functions.
// These are used for initial default values when first configuring PCSX2, or when the
// user checks "Use Default paths" option provided on most path selectors. These are not
// used otherwise, in favor of the user-configurable specifications in the ini files.
extern wxDirName GetUserLocalDataDir();
extern wxDirName GetDocuments();
@ -43,15 +49,23 @@ namespace PathDefs
}
extern DocsModeType DocsFolderMode; //
extern wxDirName SettingsFolder; // dictates where the settings folder comes from, *if* UseDefaultSettingsFolder is FALSE.
extern wxDirName CustomDocumentsFolder; // allows the specification of a custom home folder for PCSX2 documents files.
extern bool UseDefaultSettingsFolder; // when TRUE, pcsx2 derives the settings folder from the UseAdminMode
extern wxDirName Logs;
extern bool UseDefaultLogs;
extern bool UseDefaultSettingsFolder; // when TRUE, pcsx2 derives the settings folder from the DocsFolderMode
extern bool UseDefaultLogFolder;
extern bool UseDefaultPluginsFolder;
extern bool UseDefaultThemesFolder;
wxDirName GetSettingsFolder();
wxString GetSettingsFilename();
wxDirName GetLogFolder();
extern wxDirName CustomDocumentsFolder; // allows the specification of a custom home folder for PCSX2 documents files.
extern wxDirName SettingsFolder; // dictates where the settings folder comes from, *if* UseDefaultSettingsFolder is FALSE.
extern wxDirName LogFolder;
extern wxDirName InstallFolder;
extern wxDirName PluginsFolder;
extern wxDirName ThemesFolder;
extern wxDirName GetSettingsFolder();
extern wxString GetVmSettingsFilename();
extern wxString GetUiSettingsFilename();
extern wxDirName GetLogFolder();
enum AspectRatioType
{
@ -93,8 +107,6 @@ public:
{
BITFIELD32()
bool
UseDefaultPlugins:1,
UseDefaultSettings:1,
UseDefaultBios:1,
UseDefaultSnapshots:1,
UseDefaultSavestates:1,
@ -103,7 +115,6 @@ public:
BITFIELD_END
wxDirName
Plugins,
Bios,
Snapshots,
Savestates,
@ -270,8 +281,6 @@ public:
bool FullpathMatchTest( PluginsEnum_t pluginId, const wxString& cmpto ) const;
void LoadSaveUserMode( IniInterface& ini, const wxString& cwdhash );
void LoadSave( IniInterface& ini );
void LoadSaveRootItems( IniInterface& ini );
void LoadSaveMemcards( IniInterface& ini );
@ -286,6 +295,8 @@ extern void AppLoadSettings();
extern void AppSaveSettings();
extern void AppApplySettings( const AppConfig* oldconf=NULL );
extern void App_LoadSaveInstallSettings( IniInterface& ini );
extern void ConLog_LoadSaveSettings( IniInterface& ini );
extern void SysTraceLog_LoadSaveSettings( IniInterface& ini );

View File

@ -20,7 +20,6 @@
#include "MSWstuff.h"
#include "Utilities/IniInterface.h"
#include "Utilities/HashMap.h"
#include "DebugTools/Debug.h"
#include "Dialogs/ModalPopups.h"
@ -55,142 +54,6 @@ static void CpuCheckSSE2()
g_Conf->EmuOptions.Cpu.Recompiler.EnableVU1 = false;
}
void Pcsx2App::WipeUserModeSettings()
{
wxDirName usrlocaldir = PathDefs::GetUserLocalDataDir();
if( !usrlocaldir.Exists() ) return;
wxString cwd( Path::Normalize( wxGetCwd() ) );
#ifdef __WXMSW__
cwd.MakeLower();
#endif
u32 hashres = HashTools::Hash( (char*)cwd.c_str(), cwd.Length()*sizeof(wxChar) );
wxFileName usermodefile( FilenameDefs::GetUsermodeConfig() );
usermodefile.SetPath( usrlocaldir.ToString() );
ScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
FastFormatUnicode groupname;
groupname.Write( L"CWD.%08x", hashres );
Console.WriteLn( "(UserModeSettings) Removing entry:" );
Console.Indent().WriteLn( L"Path: %s\nHash:%s", cwd.c_str(), groupname.c_str() );
conf_usermode->DeleteGroup( groupname );
}
static void DoFirstTimeWizard()
{
// first time startup, so give the user the choice of user mode:
while(true)
{
// PCSX2's FTWizard allows improptu restarting of the wizard without cancellation. This is
// typically used to change the user's language selection.
FirstTimeWizard wiz( NULL );
if( wiz.RunWizard( wiz.GetUsermodePage() ) ) break;
if (wiz.GetReturnCode() != pxID_RestartWizard)
throw Exception::StartupAborted( L"User canceled FirstTime Wizard." );
Console.WriteLn( Color_StrongBlack, "Restarting First Time Wizard!" );
}
}
// User mode settings can't be stored in the CWD for two reasons:
// (a) the user may not have permission to do so (most obvious)
// (b) it would result in sloppy usermode.ini found all over a hard drive if people runs the
// exe from many locations (ugh).
//
// So better to use the registry on Win32 and a "default ini location" config file under Linux,
// and store the usermode settings for the CWD based on the CWD's hash.
//
void Pcsx2App::ReadUserModeSettings()
{
wxDirName usrlocaldir = PathDefs::GetUserLocalDataDir();
if( !usrlocaldir.Exists() )
{
Console.WriteLn( L"Creating UserLocalData folder: " + usrlocaldir.ToString() );
usrlocaldir.Mkdir();
}
wxString cwd( Path::Normalize( wxGetCwd() ) );
#ifdef __WXMSW__
cwd.MakeLower();
#endif
u32 hashres = HashTools::Hash( (char*)cwd.c_str(), cwd.Length()*sizeof(wxChar) );
wxFileName usermodefile( FilenameDefs::GetUsermodeConfig() );
usermodefile.SetPath( usrlocaldir.ToString() );
ScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
FastFormatUnicode groupname;
groupname.Write( L"CWD.%08x", hashres );
bool hasGroup = conf_usermode->HasGroup( groupname );
bool forceWiz = Startup.ForceWizard || !hasGroup;
if( !forceWiz )
{
conf_usermode->SetPath( groupname );
forceWiz = !conf_usermode->HasEntry( L"DocumentsFolderMode" );
conf_usermode->SetPath( L".." );
}
if( forceWiz )
{
// Beta Warning!
#if 0
if( !hasGroup )
{
wxDialogWithHelpers beta( NULL, _fmt("Welcome to %s %u.%u.%u (r%u)", pxGetAppName().c_str(), PCSX2_VersionHi, PCSX2_VersionMid, PCSX2_VersionLo, SVN_REV ));
beta.SetMinWidth(480);
beta += beta.Heading(
L"PCSX2 0.9.7 is a work-in-progress. We are in the middle of major rewrites of the user interface, and some parts "
L"of the program have *NOT* been re-implemented yet. Options will be missing or disabled. Horrible crashes might be present. Enjoy!"
);
beta += StdPadding*2;
beta += new wxButton( &beta, wxID_OK ) | StdCenter();
beta.ShowModal();
}
#endif
DoFirstTimeWizard();
// Save user's new settings
IniSaver saver( *conf_usermode );
g_Conf->LoadSaveUserMode( saver, groupname );
AppConfig_OnChangedSettingsFolder( true );
AppSaveSettings();
}
else
{
// usermode.ini exists and is populated with valid data -- assume User Documents mode,
// unless the ini explicitly specifies otherwise.
DocsFolderMode = DocsFolder_User;
IniLoader loader( *conf_usermode );
g_Conf->LoadSaveUserMode( loader, groupname );
if( !wxFile::Exists( GetSettingsFilename() ) )
{
// user wiped their pcsx2.ini -- needs a reconfiguration via wizard!
DoFirstTimeWizard();
// Save user's new settings
IniSaver saver( *conf_usermode );
g_Conf->LoadSaveUserMode( saver, groupname );
AppConfig_OnChangedSettingsFolder( true );
AppSaveSettings();
}
}
// force unload plugins loaded by the wizard. If we don't do this the recompilers might
// fail to allocate the memory they need to function.
UnloadPlugins();
}
void Pcsx2App::DetectCpuAndUserMode()
{
AffinityAssert_AllowFrom_MainUI();
@ -208,7 +71,11 @@ void Pcsx2App::DetectCpuAndUserMode()
.SetUserMsg(_("SSE extensions are not available. PCSX2 requires a cpu that supports the SSE instruction set."));
}
ReadUserModeSettings();
if (!TestForPortableInstall())
{
ReadUserModeSettings();
}
AppConfig_OnChangedSettingsFolder();
}
@ -286,16 +153,16 @@ void Pcsx2App::AllocateCoreStuffs()
wxDialogWithHelpers exconf( NULL, _("PCSX2 Recompiler Error(s)") );
exconf += 12;
exconf += exconf.Heading( pxE( "!Notice:RecompilerInit:Header",
L"Warning: Some of the configured PS2 recompilers failed to initialize and have been disabled:" )
);
wxTextCtrl* scrollableTextArea = new wxTextCtrl(
&exconf, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
wxTE_READONLY | wxTE_MULTILINE | wxTE_WORDWRAP
);
exconf += 12;
exconf += exconf.Heading( pxE( "!Notice:RecompilerInit:Header",
L"Warning: Some of the configured PS2 recompilers failed to initialize and have been disabled:" )
);
exconf += 6;
exconf += scrollableTextArea | pxExpand.Border(wxALL, 16);
@ -414,7 +281,7 @@ bool Pcsx2App::ParseOverrides( wxCmdLineParser& parser )
if (parser.Found( L"cfg", &dest ) && !dest.IsEmpty())
{
Console.Warning( L"Config file override: " + dest );
Overrides.SettingsFile = dest;
Overrides.VmSettingsFile = dest;
}
Overrides.DisableSpeedhacks = parser.Found(L"nohacks");

View File

@ -42,13 +42,6 @@ DEFINE_EVENT_TYPE( pxEvt_LogicalVsync );
DEFINE_EVENT_TYPE( pxEvt_ThreadTaskTimeout_SysExec );
DocsModeType DocsFolderMode = DocsFolder_User;
wxDirName SettingsFolder;
wxDirName CustomDocumentsFolder;
bool UseDefaultSettingsFolder = true;
wxDirName Logs;
bool UseDefaultLogs = true;
ScopedPtr<AppConfig> g_Conf;
template<typename DialogType>

345
pcsx2/gui/AppUserMode.cpp Normal file
View File

@ -0,0 +1,345 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "MainFrame.h"
#include "Utilities/IniInterface.h"
#include "Utilities/HashMap.h"
#include "Dialogs/ModalPopups.h"
#include <wx/stdpaths.h>
#include "wx/msw/regconf.h"
DocsModeType DocsFolderMode = DocsFolder_User;
bool UseDefaultSettingsFolder = true;
bool UseDefaultLogFolder = true;
bool UseDefaultPluginsFolder = true;
bool UseDefaultThemesFolder = true;
wxDirName CustomDocumentsFolder;
wxDirName SettingsFolder;
wxDirName LogFolder;
wxDirName InstallFolder;
wxDirName PluginsFolder;
wxDirName ThemesFolder;
enum UserLocalDataType
{
// Use the system defined user local data folder (typically an area outside the user's
// documents folder, but within user read/write permissions zoning; such that it does not
// clutter user document space).
UserLocalFolder_System,
// Uses the directory containing PCSX2.exe, or the current working directory (if the PCSX2
// directory could not be determined). This is considered 'portable' mode, and is typically
// detected by PCSX2 on application startup, by looking for a pcsx2_portable.ini file in
// said locations.
UserLocalFolder_Portable,
};
// The UserLocalData folder can be redefined depending on whether or not PCSX2 is in
// "portable install" mode or not. when PCSX2 has been configured for portable install, the
// UserLocalData folder is the current working directory.
//
static UserLocalDataType UserLocalDataMode;
static wxFileName GetPortableIniPath()
{
wxString programFullPath = wxStandardPaths::Get().GetExecutablePath();
wxDirName programDir( wxFileName(programFullPath).GetPath() );
return programDir + "pcsx2_portable.ini";
}
static wxString GetMsg_PortableModeRights()
{
return pxE( "!Error:PortableModeRights",
L"Please ensure that these folders are created and that your user account is granted "
L"write permissions to them -- or re-run PCSX2 with elevated (administrator) rights, which "
L"should grant PCSX2 the ability to create the necessary folders itself. If you "
L"do not have elevated rights on this computer, then you will need to switch to User "
L"Documents mode (click button below)."
);
};
bool Pcsx2App::TestUserPermissionsRights( const wxDirName& testFolder, wxString& createFailedStr, wxString& accessFailedStr )
{
// We need to individually verify read/write permission for each PCSX2 user documents folder.
// If any of the folders are not writable, then the user should be informed asap via
// friendly and courteous dialog box!
const wxDirName PermissionFolders[] =
{
PathDefs::Base::Settings(),
PathDefs::Base::MemoryCards(),
PathDefs::Base::Savestates(),
PathDefs::Base::Snapshots(),
PathDefs::Base::Logs(),
#ifdef PCSX2_DEVBUILD
PathDefs::Base::Dumps(),
#endif
};
FastFormatUnicode createme, accessme;
for (uint i=0; i<ArraySize(PermissionFolders); ++i)
{
wxDirName folder( testFolder + PermissionFolders[i] );
if (!folder.Mkdir())
createme += L"\t" + folder.ToString() + L"\n";
if (!folder.IsWritable())
accessme += L"\t" + folder.ToString() + L"\n";
}
if (!accessme.IsEmpty())
{
accessFailedStr = (wxString)_("The following folders exist, but are not writable:") + L"\n" + accessme;
}
if (!createme.IsEmpty())
{
createFailedStr = (wxString)_("The following folders are missing and cannot be created:") + L"\n" + createme;
}
return (createFailedStr.IsEmpty() && accessFailedStr.IsEmpty());
}
// Portable installations are assumed to be run in either administrator rights mode, or run
// from "insecure media" such as a removable flash drive. In these cases, the default path for
// PCSX2 user documents becomes ".", which is the current working directory.
//
// Portable installation mode is typically enabled via the presence of an INI file in the
// same directory that PCSX2 is installed to.
//
bool Pcsx2App::TestForPortableInstall()
{
UserLocalDataMode = UserLocalFolder_System;
const wxFileName portableIniFile( GetPortableIniPath() );
const wxDirName portableDocsFolder( portableIniFile.GetPath() );
if (portableIniFile.FileExists())
{
wxString FilenameStr = portableIniFile.GetFullPath();
Console.WriteLn( L"(UserMode) Found portable install ini @ %s", FilenameStr.c_str() );
// Just because the portable ini file exists doesn't mean we can actually run in portable
// mode. In order to determine our read/write permissions to the PCSX2, we must try to
// modify the configured documents folder, and catch any ensuing error.
ScopedPtr<wxFileConfig> conf_portable( OpenFileConfig( portableIniFile.GetFullPath() ) );
conf_portable->SetRecordDefaults(false);
wxString iniFolder = conf_portable->Read( L"IniFolder", wxGetCwd() );
while( true )
{
wxString accessFailedStr, createFailedStr;
if (TestUserPermissionsRights( portableDocsFolder, createFailedStr, accessFailedStr )) break;
wxDialogWithHelpers dialog( NULL, AddAppName(_("Portable mode error - %s")) );
wxTextCtrl* scrollText = new wxTextCtrl(
&dialog, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
wxTE_READONLY | wxTE_MULTILINE | wxTE_WORDWRAP
);
if (!createFailedStr.IsEmpty())
scrollText->AppendText( createFailedStr + L"\n" );
if (!accessFailedStr.IsEmpty())
scrollText->AppendText( accessFailedStr + L"\n" );
dialog += dialog.Heading( _("PCSX2 has been installed as a portable application but cannot run due to the following errors:" ) );
dialog += scrollText | pxExpand.Border(wxALL, 16);
dialog += 6;
dialog += dialog.Text( GetMsg_PortableModeRights() );
// [TODO] : Add url for platform-relevant user permissions tutorials? (low priority)
wxWindowID result = pxIssueConfirmation( dialog,
MsgButtons().Retry().Cancel().Custom(_("Switch to User Documents Mode"), "switchmode")
);
switch (result)
{
case wxID_CANCEL:
throw Exception::StartupAborted( L"User canceled portable mode due to insufficient user access/permissions." );
case wxID_RETRY:
// do nothing (continues while loop)
break;
case pxID_CUSTOM:
// Pretend like the portable ini was never found!
return false;
}
}
// Success -- all user-based folders have write access. PCSX2 should be
// able to run error-free!
UserLocalDataMode = UserLocalFolder_Portable;
return true;
}
return false;
}
// Removes both portable ini and user local ini entry conforming to this instance of PCSX2.
void Pcsx2App::WipeUserModeSettings()
{
if (UserLocalDataMode == UserLocalFolder_Portable)
{
// Remove the user local portable ini definition (if possible).
// If the user does not have admin rights to the PCSX2 folder, removing the file may fail.
// PCSX2 does checks for admin rights on start-up if the file is found, though,
// so there should (in theory) be no sane way for this to error if we're running
// in portable mode.
wxFileName portableIniFile( GetPortableIniPath() );
if (portableIniFile.FileExists())
wxRemoveFile(portableIniFile.GetFullPath());
}
// Remove the user-local ini entry conforming to this instance of PCSX2.
// Remove this regardless if PCSX2 is in portable mode, since otherwise these settings
// would be used when the user restarts PCSX2, and that might be undesirable.
wxDirName usrlocaldir = PathDefs::GetUserLocalDataDir();
if( !usrlocaldir.Exists() ) return;
wxString cwd( Path::Normalize( wxGetCwd() ) );
#ifdef __WXMSW__
cwd.MakeLower();
#endif
u32 hashres = HashTools::Hash( (char*)cwd.c_str(), cwd.Length()*sizeof(wxChar) );
wxFileName usermodefile( FilenameDefs::GetUsermodeConfig() );
usermodefile.SetPath( usrlocaldir.ToString() );
ScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
FastFormatUnicode groupname;
groupname.Write( L"CWD.%08x", hashres );
Console.WriteLn( "(UserMode) Removing entry:" );
Console.Indent().WriteLn( L"Path: %s\nHash:%s", cwd.c_str(), groupname.c_str() );
conf_usermode->DeleteGroup( groupname );
}
static void DoFirstTimeWizard()
{
// first time startup, so give the user the choice of user mode:
while(true)
{
// PCSX2's FTWizard allows improptu restarting of the wizard without cancellation. This is
// typically used to change the user's language selection.
FirstTimeWizard wiz( NULL );
if( wiz.RunWizard( wiz.GetUsermodePage() ) ) break;
if (wiz.GetReturnCode() != pxID_RestartWizard)
throw Exception::StartupAborted( L"User canceled FirstTime Wizard." );
Console.WriteLn( Color_StrongBlack, "Restarting First Time Wizard!" );
}
}
void Pcsx2App::ReadUserModeSettings()
{
// Implementation Notes:
//
// As of 0.9.8 and beyond, PCSX2's versioning should be strong enough to base ini and
// plugin compatibility on version information alone. This in turn allows us to ditch
// the old system (CWD-based ini file mess) in favor of a system that simply stores
// most core application-level settings in the registry.
// [TODO] : wxWidgets 2.8 does not yet support the Windows Vista/7 APPDATA feature (which
// resolves to c:\programdata\ on standard installs). I'm too lazy to write our own
// register code to uncover the value of CSLID_APPDATA, so until we upgrade wx, we'll
// just store the configuration files in the user local data directory instead.
ScopedPtr<wxConfigBase> conf_install;
#ifdef __WXMSW__
conf_install = new wxRegConfig();
#else
// FIXME!! Linux / Mac
// Where the heck should this information be stored?
wxDirName usrlocaldir( PathDefs::GetUserLocalDataDir() );
//wxDirName usrlocaldir( wxStandardPaths::Get().GetDataDir() );
if( !usrlocaldir.Exists() )
{
Console.WriteLn( L"Creating UserLocalData folder: " + usrlocaldir.ToString() );
usrlocaldir.Mkdir();
}
wxFileName usermodefile( GetAppName() + L"-reg.ini" );
usermodefile.SetPath( usrlocaldir.ToString() );
conf_install = OpenFileConfig( usermodefile.GetFullPath() )
#endif
conf_install->SetRecordDefaults(false);
bool runWiz;
conf_install->Read( L"RunWizard", &runWiz, true );
if( !Startup.ForceWizard && !runWiz )
{
IniLoader loader( conf_install );
App_LoadSaveInstallSettings( loader );
return;
}
// ----------------------------
// Run the First Time Wizard!
// ----------------------------
// Beta Warning!
#if 0
if( !hasGroup )
{
wxDialogWithHelpers beta( NULL, _fmt("Welcome to %s %u.%u.%u (r%u)", pxGetAppName().c_str(), PCSX2_VersionHi, PCSX2_VersionMid, PCSX2_VersionLo, SVN_REV ));
beta.SetMinWidth(480);
beta += beta.Heading(
L"PCSX2 0.9.7 is a work-in-progress. We are in the middle of major rewrites of the user interface, and some parts "
L"of the program have *NOT* been re-implemented yet. Options will be missing or disabled. Horrible crashes might be present. Enjoy!"
);
beta += StdPadding*2;
beta += new wxButton( &beta, wxID_OK ) | StdCenter();
beta.ShowModal();
}
#endif
DoFirstTimeWizard();
// Save user's new settings
IniSaver saver( *conf_install );
App_LoadSaveInstallSettings( saver );
AppConfig_OnChangedSettingsFolder( true );
AppSaveSettings();
// Wizard completed successfully, so let's not torture the user with this crap again!
conf_install->Write( L"RunWizard", false );
// force unload plugins loaded by the wizard. If we don't do this the recompilers might
// fail to allocate the memory they need to function.
ShutdownPlugins();
UnloadPlugins();
}

View File

@ -237,7 +237,7 @@ void FirstTimeWizard::OnPageChanging( wxWizardEvent& evt )
if( page == 0 )
{
if( wxFile::Exists( GetSettingsFilename() ) )
if( wxFile::Exists(GetUiSettingsFilename()) || wxFile::Exists(GetVmSettingsFilename()) )
{
// Asks the user if they want to import or overwrite the existing settings.

View File

@ -235,15 +235,16 @@ Dialogs::ComponentsConfigDialog::ComponentsConfigDialog(wxWindow* parent)
wxGetApp().PostMethod( CheckPluginsOverrides );
}
Dialogs::InterfaceConfigDialog::InterfaceConfigDialog(wxWindow *parent)
: BaseConfigurationDialog( parent, AddAppName(_("Language Selector - %s")), 400 )
: BaseConfigurationDialog( parent, AddAppName(_("Appearance/Themes - %s")), 400 )
{
ScopedBusyCursor busy( Cursor_ReallyBusy );
CreateListbook( wxGetApp().GetImgList_Config() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage<StandardPathsPanel> ( pxL("Appearance"), cfgid.Appearance );
AddPage<AppearanceThemesPanel> ( pxL("Appearance"), cfgid.Appearance );
AddPage<StandardPathsPanel> ( pxL("Folders"), cfgid.Paths );
AddListbook();
@ -252,3 +253,25 @@ Dialogs::InterfaceConfigDialog::InterfaceConfigDialog(wxWindow *parent)
//*this += new Panels::LanguageSelectionPanel( this ) | pxCenter;
//wxDialogWithHelpers::AddOkCancel( NULL, false );
}
// ------------------------------------------------------------------------
Panels::AppearanceThemesPanel::AppearanceThemesPanel( wxWindow* parent )
: BaseApplicableConfigPanel( parent )
{
}
AppearanceThemesPanel::~AppearanceThemesPanel() throw()
{
}
void AppearanceThemesPanel::Apply()
{
}
void AppearanceThemesPanel::AppStatusEvent_OnSettingsApplied()
{
}

View File

@ -83,7 +83,8 @@ static void WipeSettings()
wxGetApp().CleanupRestartable();
wxGetApp().CleanupResources();
wxRemoveFile( GetSettingsFilename() );
wxRemoveFile( GetUiSettingsFilename() );
wxRemoveFile( GetVmSettingsFilename() );
// FIXME: wxRmdir doesn't seem to work here for some reason (possible file sharing issue
// with a plugin that leaves a file handle dangling maybe?). But deleting the inis folder

View File

@ -17,7 +17,6 @@
#include "App.h"
#include "ConfigurationPanels.h"
#include "Utilities/ScopedPtr.h"
#include "ps2/BiosTools.h"
#include <wx/dir.h>
@ -29,6 +28,18 @@ using namespace pxSizerFlags;
// =====================================================================================================
// BaseSelectorPanel
// =====================================================================================================
// This base class provides event hookups and virtual functions for enumerating items in a folder.
// The most important feature of this base panel is that enumeration is done when the panel is first
// *shown*, not when it is created. This functionality allows the panel to work either as a stand alone
// dialog, a child of a complex tabbed dialog, and as a member of a wxWizard!
//
// In addition, this panel automatically intercepts and responds to DIRPICKER messages, so that your
// panel may provide a dir picker to the user.
//
// [TODO] : wxWidgets 2.9.1 provides a class for watching directory contents changes. When PCSX2 is
// upgraded to wx2.9/3.0, it should incorporate such functionality into this base class. (for now
// we just provide the user with a "refresh" button).
//
Panels::BaseSelectorPanel::BaseSelectorPanel( wxWindow* parent )
: BaseApplicableConfigPanel( parent, wxVERTICAL )
{

View File

@ -417,6 +417,21 @@ namespace Panels
StandardPathsPanel( wxWindow* parent );
};
// --------------------------------------------------------------------------------------
// AppearanceThemesPanel
// --------------------------------------------------------------------------------------
class AppearanceThemesPanel : public BaseApplicableConfigPanel
{
typedef BaseApplicableConfigPanel _parent;
public:
virtual ~AppearanceThemesPanel() throw();
AppearanceThemesPanel( wxWindow* parent );
void Apply();
void AppStatusEvent_OnSettingsApplied();
};
// --------------------------------------------------------------------------------------
// BaseSelectorPanel
// --------------------------------------------------------------------------------------
@ -437,11 +452,47 @@ namespace Panels
protected:
void OnRefreshSelections( wxCommandEvent& evt );
// This method is called when the enumeration contents have changed. The implementing
// class should populate or re-populate listbox/selection components when invoked.
//
virtual void DoRefresh()=0;
// This method is called when an event has indicated that the enumeration status of the
// selector may have changed. The implementing class should re-enumerate the folder/source
// data and return either TRUE (enumeration status unchanged) or FALSE (enumeration status
// changed).
//
// If the implementation returns FALSE, then the BaseSelectorPanel will invoke a call to
// DoRefresh() [which also must be implemented]
//
virtual bool ValidateEnumerationStatus()=0;
void OnShow(wxShowEvent& evt);
};
// --------------------------------------------------------------------------------------
// ThemeSelectorPanel
// --------------------------------------------------------------------------------------
class ThemeSelectorPanel : public BaseSelectorPanel
{
typedef BaseSelectorPanel _parent;
protected:
ScopedPtr<wxArrayString> m_ThemeList;
wxListBox* m_ComboBox;
DirPickerPanel* m_FolderPicker;
public:
virtual ~ThemeSelectorPanel() throw();
ThemeSelectorPanel( wxWindow* parent );
protected:
virtual void Apply();
virtual void AppStatusEvent_OnSettingsApplied();
virtual void DoRefresh();
virtual bool ValidateEnumerationStatus();
};
// --------------------------------------------------------------------------------------
// BiosSelectorPanel
// --------------------------------------------------------------------------------------

View File

@ -22,15 +22,16 @@ using namespace pxSizerFlags;
static const int BetweenFolderSpace = 5;
// ------------------------------------------------------------------------
Panels::BasePathsPanel::BasePathsPanel( wxWindow* parent )
: wxPanelWithHelpers( parent, wxVERTICAL )
{
}
// ------------------------------------------------------------------------
Panels::StandardPathsPanel::StandardPathsPanel( wxWindow* parent ) :
BasePathsPanel( parent )
// --------------------------------------------------------------------------------------
// Panels::StandardPathsPanel (implementations)
// --------------------------------------------------------------------------------------
Panels::StandardPathsPanel::StandardPathsPanel( wxWindow* parent )
: BasePathsPanel( parent )
{
*this += BetweenFolderSpace;
*this += (new DirPickerPanel( this, FolderId_Savestates,

View File

@ -0,0 +1,113 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of te License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "ConfigurationPanels.h"
#include <wx/dir.h>
#include <wx/filepicker.h>
#include <wx/listbox.h>
#include <wx/zipstrm.h>
using namespace pxSizerFlags;
// =====================================================================================================
// ThemeSelectorPanel
// =====================================================================================================
Panels::ThemeSelectorPanel::ThemeSelectorPanel( wxWindow* parent )
: _parent( parent )
{
SetMinWidth( 480 );
m_ComboBox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE | wxLB_SORT | wxLB_NEEDED_SB );
m_FolderPicker = new DirPickerPanel( this, FolderId_Themes,
_("Themes Search Path:"), // static box label
_("Select folder containing PCSX2 visual themes") // dir picker popup label
);
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 ) ) );
m_FolderPicker->SetStaticDesc( _("Click the Browse button to select a different folder containing PCSX2 visual themes.") );
wxButton* refreshButton = new wxButton( this, wxID_ANY, _("Refresh list") );
*this += Label(_("Select a visual theme:"));
*this += m_ComboBox | StdExpand();
*this += refreshButton | pxBorder(wxLEFT, StdPadding);
*this += 8;
*this += m_FolderPicker | StdExpand();
Connect( refreshButton->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ThemeSelectorPanel::OnRefreshSelections) );
}
Panels::ThemeSelectorPanel::~ThemeSelectorPanel() throw ()
{
}
void Panels::ThemeSelectorPanel::Apply()
{
}
void Panels::ThemeSelectorPanel::AppStatusEvent_OnSettingsApplied()
{
}
bool Panels::ThemeSelectorPanel::ValidateEnumerationStatus()
{
bool validated = true;
// Impl Note: ScopedPtr used so that resources get cleaned up if an exception
// occurs during file enumeration.
ScopedPtr<wxArrayString> themelist( new wxArrayString() );
if( m_FolderPicker->GetPath().Exists() )
{
wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), themelist, L"*.zip;*.p2ui", wxDIR_FILES );
wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), themelist, L"*.*", wxDIR_DIRS );
}
if( !m_ThemeList || (*themelist != *m_ThemeList) )
validated = false;
m_ThemeList.SwapPtr( themelist );
return validated;
}
void Panels::ThemeSelectorPanel::DoRefresh()
{
if( !m_ThemeList ) return;
m_ComboBox->Clear();
const wxFileName right( g_Conf->FullpathToBios() );
for( size_t i=0; i<m_ThemeList->GetCount(); ++i )
{
wxString description;
//if( !IsBIOS((*m_BiosList)[i], description) ) continue;
//wxZipInputStream woot;
int sel = m_ComboBox->Append( description, (void*)i );
if( wxFileName((*m_ThemeList)[i] ) == right )
m_ComboBox->SetSelection( sel );
}
}

View File

@ -1901,6 +1901,10 @@
RelativePath="..\..\gui\AppRes.cpp"
>
</File>
<File
RelativePath="..\..\gui\AppUserMode.cpp"
>
</File>
<File
RelativePath="..\..\gui\ConsoleLogger.cpp"
>
@ -2640,6 +2644,10 @@
RelativePath="..\..\gui\Panels\SpeedhacksPanel.cpp"
>
</File>
<File
RelativePath="..\..\gui\Panels\ThemeSelectorPanel.cpp"
>
</File>
<File
RelativePath="..\..\gui\Panels\VideoPanel.cpp"
>