Patch from Jake.Stine: portable/registered install modes fixes:

-----------------------
(Jake:) here's my final patch for the pcsx2 inis and portable mode stuff:
it removes the ability to modify paths in portable mode (patchs are fixed to cwd anyway). Paths are still displayed for user convenience, read-only.
Also fixes some minor bugs and annoyances reported by users.
That should pretty well clean up most of what I broke when I rused the portable install feature in a few weeks ago.
May want to review it first, I still haven't had much time or inclination to do my usual amount of code quality control.
-----------------------
(avih:) I tested it briefly and nothing seemed horribly broken (read: looks OK after little testing). Didn't do a proper code review though.


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4297 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
avihal@gmail.com 2011-02-13 21:00:36 +00:00
parent 1e6f280021
commit 428675b3d0
9 changed files with 142 additions and 69 deletions

View File

@ -98,12 +98,12 @@ namespace PathDefs
{
AffinityAssert_AllowFrom_MainUI();
if (UserLocalDataMode == UserLocalFolder_System)
if (InstallationMode == InstallMode_Registered)
{
static const wxDirName cwdCache( (wxDirName)Path::Normalize(wxGetCwd()) );
return cwdCache;
}
else if (UserLocalDataMode == UserLocalFolder_Portable)
else if (InstallationMode == InstallMode_Portable)
{
static const wxDirName appCache( (wxDirName)
wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath() );
@ -444,13 +444,23 @@ AppConfig::AppConfig()
// ------------------------------------------------------------------------
void App_LoadSaveInstallSettings( IniInterface& ini )
{
// Portable installs of PCSX2 should not save any of the following information to
// the INI file. Only the Run First Time Wizard option is saved, and that's done
// from EstablishAppUserMode code. All other options have assumed (fixed) defaults in
// portable mode which cannot be changed/saved.
// Note: Settins are still *loaded* from portable.ini, in case the user wants to do
// low-level overrides of the default behavior of portable mode installs.
if (ini.IsSaving() && (InstallationMode == InstallMode_Portable)) return;
static const wxChar* DocsFolderModeNames[] =
{
L"User",
L"Custom",
};
ini.EnumEntry( L"DocumentsFolderMode", DocsFolderMode, DocsFolderModeNames, (UserLocalDataMode == UserLocalFolder_System) ? DocsFolder_User : DocsFolder_Custom);
ini.EnumEntry( L"DocumentsFolderMode", DocsFolderMode, DocsFolderModeNames, (InstallationMode == InstallMode_Registered) ? DocsFolder_User : DocsFolder_Custom);
ini.Entry( L"CustomDocumentsFolder", CustomDocumentsFolder, PathDefs::AppRoot() );

View File

@ -67,21 +67,24 @@ extern wxString GetVmSettingsFilename();
extern wxString GetUiSettingsFilename();
extern wxDirName GetLogFolder();
enum UserLocalDataType
enum InstallationModeType
{
// 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,
// Use the user defined folder selections. These can be anywhere on a user's hard drive,
// though by default the binaries (plugins, themes) are located in Install_Dir (registered
// by the installer), and the user files (screenshots, inis) are in the user's documents
// folder. All folders are changable within the GUI.
InstallMode_Registered,
// 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,
// In this mode, both Install_Dir and UserDocuments folders default the directory containing
// PCSX2.exe, or the current working directory (if the PCSX2 directory could not be determined).
// Folders cannot be changed from within the gui, however the fixed defaults can be manually
// specified in the portable.ini by power users/devs.
//
// This mode is typically enabled by the presence of a 'portable.ini' in the folder.
InstallMode_Portable,
};
extern UserLocalDataType UserLocalDataMode;
extern InstallationModeType InstallationMode;
enum AspectRatioType
{

View File

@ -44,14 +44,14 @@ wxDirName ThemesFolder;
// "portable install" mode or not. when PCSX2 has been configured for portable install, the
// UserLocalData folder is the current working directory.
//
UserLocalDataType UserLocalDataMode;
InstallationModeType InstallationMode;
static wxFileName GetPortableIniPath()
{
wxString programFullPath = wxStandardPaths::Get().GetExecutablePath();
wxDirName programDir( wxFileName(programFullPath).GetPath() );
return programDir + "pcsx2_portable.ini";
return programDir + "portable.ini";
}
static wxString GetMsg_PortableModeRights()
@ -118,7 +118,7 @@ bool Pcsx2App::TestUserPermissionsRights( const wxDirName& testFolder, wxString&
//
wxConfigBase* Pcsx2App::TestForPortableInstall()
{
UserLocalDataMode = UserLocalFolder_System;
InstallationMode = InstallMode_Registered;
const wxFileName portableIniFile( GetPortableIniPath() );
const wxDirName portableDocsFolder( portableIniFile.GetPath() );
@ -186,7 +186,7 @@ wxConfigBase* Pcsx2App::TestForPortableInstall()
// Success -- all user-based folders have write access. PCSX2 should be able to run error-free!
// Force-set the custom documents mode, and set the
UserLocalDataMode = UserLocalFolder_Portable;
InstallationMode = InstallMode_Portable;
DocsFolderMode = DocsFolder_Custom;
CustomDocumentsFolder = portableDocsFolder;
return conf_portable.DetachPtr();
@ -198,7 +198,7 @@ wxConfigBase* Pcsx2App::TestForPortableInstall()
// Removes both portable ini and user local ini entry conforming to this instance of PCSX2.
void Pcsx2App::WipeUserModeSettings()
{
if (UserLocalDataMode == UserLocalFolder_Portable)
if (InstallationMode == InstallMode_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.

View File

@ -149,13 +149,7 @@ void Dialogs::SysConfigDialog::AddPresetsControl()
pxEt( "!Notice:Tooltip:Presets:Checkbox",
L"The Presets apply speed hacks, some recompiler options and some game fixes known to boost speed.\n"
L"Known important game fixes ('Patches') will be applied automatically.\n\n"
//This creates nested macros = not working. Un/comment manually if needed.
//#ifdef PRESETS_USE_APPLIED_CONFIG_ON_UNCHECK
// L"--> Uncheck to modify settings manually."
// L"If you want to manually modify with a preset as a base, apply this preset, then uncheck."
//#else
L"--> Uncheck to modify settings manually (with current preset as base)"
//#endif
)
);
m_check_presets->SetValue(!!g_Conf->EnablePresets);

View File

@ -107,7 +107,8 @@ Panels::BiosSelectorPanel::BiosSelectorPanel( wxWindow* parent )
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 where PCSX2 will look for PS2 BIOS roms.") );
if (InstallationMode != InstallMode_Portable)
m_FolderPicker->SetStaticDesc( _("Click the Browse button to select a different folder where PCSX2 will look for PS2 BIOS roms.") );
wxButton* refreshButton = new wxButton( this, wxID_ANY, _("Refresh list") );

View File

@ -44,6 +44,8 @@ namespace Panels
FoldersEnum_t m_FolderId;
wxDirPickerCtrl* m_pickerCtrl;
pxCheckBox* m_checkCtrl;
wxTextCtrl* m_textCtrl;
wxButton* b_explore;
public:
DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel );
@ -68,6 +70,8 @@ namespace Panels
protected:
void Init( FoldersEnum_t folderid, const wxString& dialogLabel, bool isCompact );
void InitForPortableMode( const wxString& normalized );
void InitForRegisteredMode( const wxString& normalized, const wxString& dialogLabel, bool isCompact );
void UseDefaultPath_Click( wxCommandEvent &event );
void Explore_Click( wxCommandEvent &event );

View File

@ -32,8 +32,10 @@ static wxString GetNormalizedConfigFolder( FoldersEnum_t folderId )
// Pass me TRUE if the default path is to be used, and the DirPickerCtrl disabled from use.
void Panels::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
{
if (!m_pickerCtrl) return;
m_pickerCtrl->Enable( !someNoteworthyBoolean );
if( someNoteworthyBoolean )
if (someNoteworthyBoolean)
{
wxString normalized( Path::Normalize( PathDefs::Get( m_FolderId ) ) );
m_pickerCtrl->SetPath( normalized );
@ -52,13 +54,17 @@ void Panels::DirPickerPanel::UseDefaultPath_Click( wxCommandEvent &evt )
void Panels::DirPickerPanel::Explore_Click( wxCommandEvent &evt )
{
wxString path( m_pickerCtrl->GetPath() );
if( !wxDirExists(path) )
wxDirName path( GetPath() );
if (!pxAssertDev( path.IsOk(), "This DirPickerPanel could not find valid or meaningful path data." ))
return;
if (!path.Exists())
{
wxDialogWithHelpers createPathDlg( NULL, _("Path does not exist") );
createPathDlg.SetMinWidth( 600 );
createPathDlg += createPathDlg.Text( path ) | StdCenter();
createPathDlg += createPathDlg.Text( path.ToString() ) | StdCenter();
createPathDlg += createPathDlg.Heading( pxE( "!Notice:DirPicker:CreatePath",
L"The specified path/directory does not exist. Would you like to create it?" )
@ -70,15 +76,19 @@ void Panels::DirPickerPanel::Explore_Click( wxCommandEvent &evt )
);
if( result == wxID_CANCEL ) return;
wxDirName(path).Mkdir();
path.Mkdir();
}
pxExplore( path );
pxExplore( path.ToString() );
}
// ------------------------------------------------------------------------
// If initPath is NULL, then it's assumed the default folder is to be used, which is
// obtained from invoking the specified getDefault() function.
// There are two constructors. See the details for the 'label' parameter below for details.
//
// Parameters:
// label - label for the StaticBox that surrounds the dir picker control. If the 'label'
// parameter is not specified, the layout of the panel is assumed to be "compact" which
// lacks a static box and compresses itself onto a single line. Compact mode may be useful
// for situations where the expanded format is just too invasive.
//
Panels::DirPickerPanel::DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel )
: BaseApplicableConfigPanel( parent, wxVERTICAL, label )
@ -97,21 +107,58 @@ void Panels::DirPickerPanel::Init( FoldersEnum_t folderid, const wxString& dialo
m_FolderId = folderid;
m_pickerCtrl = NULL;
m_checkCtrl = NULL;
m_textCtrl = NULL;
b_explore = NULL;
// 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 ));
wxString normalized( GetNormalizedConfigFolder( m_FolderId ) );
if( wxFile::Exists( normalized ) )
if (wxFile::Exists( normalized ))
{
// The default path is invalid... What should we do here? hmm..
}
//if( !wxDir::Exists( normalized ) )
// wxMkdir( normalized );
#ifndef __WXGTK__
// GTK+ : The wx implementation of Explore isn't reliable, so let's not even put the
// button on the dialogs for now.
if( !isCompact )
b_explore = new wxButton( this, wxID_ANY, _("Open in Explorer") );
pxSetToolTip( b_explore, _("Open an explorer window to this folder.") );
Connect( b_explore->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DirPickerPanel::Explore_Click ) );
#endif
if (InstallationMode == InstallMode_Portable)
InitForPortableMode(normalized);
else
InitForRegisteredMode(normalized, dialogLabel, isCompact);
// wx warns when paths don't exist, but this is typically normal when the wizard
// creates its child controls. So let's ignore them.
wxDoNotLogInThisScope please;
AppStatusEvent_OnSettingsApplied(); // forces default settings based on g_Conf
}
void Panels::DirPickerPanel::InitForPortableMode( const wxString& normalized )
{
// In portable mode the path is unchangeable, and only a browse button is provided (which
// itself is windows-only at this time).
m_textCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
wxFlexGridSizer& s_lower( *new wxFlexGridSizer( 2, 0, StdPadding ) );
s_lower.AddGrowableCol( 0, 1 );
s_lower += m_textCtrl | pxExpand;
if (b_explore)
s_lower += b_explore;
*this += s_lower | pxExpand.Border(wxLEFT | wxRIGHT, StdPadding);
m_textCtrl->Disable();
}
void Panels::DirPickerPanel::InitForRegisteredMode( const wxString& normalized, const wxString& dialogLabel, bool isCompact )
{
if (!isCompact)
{
m_checkCtrl = new pxCheckBox( this, _("Use default setting") );
@ -122,6 +169,9 @@ void Panels::DirPickerPanel::Init( FoldersEnum_t folderid, const wxString& dialo
Connect( m_checkCtrl->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DirPickerPanel::UseDefaultPath_Click ) );
}
// 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, wxEmptyString, dialogLabel,
wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL | wxDIRP_DIR_MUST_EXIST
);
@ -135,7 +185,7 @@ void Panels::DirPickerPanel::Init( FoldersEnum_t folderid, const wxString& dialo
Connect( b_explore->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DirPickerPanel::Explore_Click ) );
#endif
if( isCompact )
if (isCompact)
{
wxFlexGridSizer& s_compact( *new wxFlexGridSizer( 2, 0, 4 ) );
s_compact.AddGrowableCol( 0 );
@ -143,26 +193,22 @@ void Panels::DirPickerPanel::Init( FoldersEnum_t folderid, const wxString& dialo
#ifndef __WXGTK__
s_compact += b_explore;
#endif
*this += s_compact | pxExpand; //.Border(wxLEFT | wxRIGHT | wxTOP, 5);
*this += s_compact | pxExpand;
}
else
{
wxBoxSizer& s_lower( *new wxBoxSizer( wxHORIZONTAL ) );
s_lower += m_checkCtrl | pxMiddle;
#ifndef __WXGTK__
s_lower += pxStretchSpacer(1);
s_lower += b_explore;
#endif
if (b_explore)
{
s_lower += pxStretchSpacer(1);
s_lower += b_explore;
}
*this += m_pickerCtrl | pxExpand.Border(wxLEFT | wxRIGHT | wxTOP, StdPadding);
*this += s_lower | pxExpand.Border(wxLEFT | wxRIGHT, StdPadding);
}
// wx warns when paths don't exist, but this is typically normal when the wizard
// creates its child controls. So let's ignore them.
wxDoNotLogInThisScope please;
AppStatusEvent_OnSettingsApplied(); // forces default settings based on g_Conf
}
Panels::DirPickerPanel& Panels::DirPickerPanel::SetStaticDesc( const wxString& msg )
@ -186,10 +232,10 @@ void Panels::DirPickerPanel::Reset()
{
const bool isDefault = g_Conf->Folders.IsDefault( m_FolderId );
if( m_checkCtrl )
if (m_checkCtrl)
m_checkCtrl->SetValue( isDefault );
if( m_pickerCtrl )
if (m_pickerCtrl)
{
// Important! The dirpicker panel stuff, due to however it's put together
// needs to check the enable status of this panel before setting the child
@ -198,11 +244,19 @@ void Panels::DirPickerPanel::Reset()
m_pickerCtrl->Enable( IsEnabled() ? ( m_checkCtrl ? !isDefault : true ) : false );
m_pickerCtrl->SetPath( GetNormalizedConfigFolder( m_FolderId ) );
}
if (m_textCtrl)
{
m_textCtrl->Disable();
m_textCtrl->SetValue( GetNormalizedConfigFolder( m_FolderId ) );
}
}
bool Panels::DirPickerPanel::Enable( bool enable )
{
m_pickerCtrl->Enable( enable ? (!m_checkCtrl || m_checkCtrl->GetValue()) : false );
if (m_pickerCtrl)
m_pickerCtrl->Enable( enable ? (!m_checkCtrl || m_checkCtrl->GetValue()) : false );
return _parent::Enable( enable );
}
@ -214,23 +268,21 @@ void Panels::DirPickerPanel::AppStatusEvent_OnSettingsApplied()
void Panels::DirPickerPanel::Apply()
{
if( !m_pickerCtrl ) return;
wxDirName path( GetPath() );
const wxString path( m_pickerCtrl->GetPath() );
if( !wxDir::Exists( path ) )
if (!path.Exists())
{
wxDialogWithHelpers dialog( NULL, _("Create folder?") );
dialog += dialog.Heading(AddAppName(_("A configured folder does not exist. Should %s try to create it?")));
dialog += 12;
dialog += dialog.Heading( path );
dialog += dialog.Heading( path.ToString() );
if( wxID_CANCEL == pxIssueConfirmation( dialog, MsgButtons().Custom(_("Create"), "create").Cancel(), L"CreateNewFolder" ) )
throw Exception::CannotApplySettings( this );
}
wxDirName(path).Mkdir();
g_Conf->Folders.Set( m_FolderId, m_pickerCtrl->GetPath(), m_checkCtrl ? m_checkCtrl->GetValue() : false );
path.Mkdir();
g_Conf->Folders.Set( m_FolderId, path.ToString(), m_checkCtrl ? m_checkCtrl->GetValue() : false );
}
wxDirName Panels::DirPickerPanel::GetPath() const
@ -238,11 +290,18 @@ wxDirName Panels::DirPickerPanel::GetPath() const
// The (x) ? y : z construct doesn't like y and z to be different types in gcc.
if (m_pickerCtrl)
return wxDirName(m_pickerCtrl->GetPath());
else
return wxDirName(wxEmptyString);
if (m_textCtrl)
return wxDirName(m_textCtrl->GetValue());
return wxDirName(wxEmptyString);
}
void Panels::DirPickerPanel::SetPath( const wxString& newPath )
{
m_pickerCtrl->SetPath( newPath );
if (m_pickerCtrl)
m_pickerCtrl->SetPath( newPath );
if (m_textCtrl)
m_textCtrl->SetValue( newPath );
}

View File

@ -375,7 +375,8 @@ Panels::PluginSelectorPanel::ComboBoxPanel::ComboBoxPanel( PluginSelectorPanel*
s_plugin += m_configbutton[pid];
} while( ++pi, pi->shortname != NULL );
m_FolderPicker.SetStaticDesc( _("Click the Browse button to select a different folder for PCSX2 plugins.") );
if (InstallationMode != InstallMode_Portable)
m_FolderPicker.SetStaticDesc( _("Click the Browse button to select a different folder for PCSX2 plugins.") );
*this += s_plugin | pxExpand;
*this += 6;

View File

@ -41,7 +41,8 @@ Panels::ThemeSelectorPanel::ThemeSelectorPanel( wxWindow* parent )
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.") );
if (InstallationMode != InstallMode_Portable)
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") );