From 428675b3d0258184023efb7e348067cfe3ed2837 Mon Sep 17 00:00:00 2001 From: "avihal@gmail.com" Date: Sun, 13 Feb 2011 21:00:36 +0000 Subject: [PATCH] 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 --- pcsx2/gui/AppConfig.cpp | 16 ++- pcsx2/gui/AppConfig.h | 25 ++-- pcsx2/gui/AppUserMode.cpp | 10 +- pcsx2/gui/Dialogs/SysConfigDialog.cpp | 6 - pcsx2/gui/Panels/BiosSelectorPanel.cpp | 3 +- pcsx2/gui/Panels/ConfigurationPanels.h | 4 + pcsx2/gui/Panels/DirPickerPanel.cpp | 141 ++++++++++++++++------- pcsx2/gui/Panels/PluginSelectorPanel.cpp | 3 +- pcsx2/gui/Panels/ThemeSelectorPanel.cpp | 3 +- 9 files changed, 142 insertions(+), 69 deletions(-) diff --git a/pcsx2/gui/AppConfig.cpp b/pcsx2/gui/AppConfig.cpp index 86fdc30cc3..119b6b7612 100644 --- a/pcsx2/gui/AppConfig.cpp +++ b/pcsx2/gui/AppConfig.cpp @@ -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() ); diff --git a/pcsx2/gui/AppConfig.h b/pcsx2/gui/AppConfig.h index 502e957258..a7e02342a9 100644 --- a/pcsx2/gui/AppConfig.h +++ b/pcsx2/gui/AppConfig.h @@ -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 { diff --git a/pcsx2/gui/AppUserMode.cpp b/pcsx2/gui/AppUserMode.cpp index fe11117eb0..39056fc922 100644 --- a/pcsx2/gui/AppUserMode.cpp +++ b/pcsx2/gui/AppUserMode.cpp @@ -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. diff --git a/pcsx2/gui/Dialogs/SysConfigDialog.cpp b/pcsx2/gui/Dialogs/SysConfigDialog.cpp index f549cd0896..3e6af1eaa8 100644 --- a/pcsx2/gui/Dialogs/SysConfigDialog.cpp +++ b/pcsx2/gui/Dialogs/SysConfigDialog.cpp @@ -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); diff --git a/pcsx2/gui/Panels/BiosSelectorPanel.cpp b/pcsx2/gui/Panels/BiosSelectorPanel.cpp index 4773a01795..9294d50ea0 100644 --- a/pcsx2/gui/Panels/BiosSelectorPanel.cpp +++ b/pcsx2/gui/Panels/BiosSelectorPanel.cpp @@ -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") ); diff --git a/pcsx2/gui/Panels/ConfigurationPanels.h b/pcsx2/gui/Panels/ConfigurationPanels.h index f0f9a24c9e..15fc9578ff 100644 --- a/pcsx2/gui/Panels/ConfigurationPanels.h +++ b/pcsx2/gui/Panels/ConfigurationPanels.h @@ -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 ); diff --git a/pcsx2/gui/Panels/DirPickerPanel.cpp b/pcsx2/gui/Panels/DirPickerPanel.cpp index 6da0a57dc1..fa29b8965d 100644 --- a/pcsx2/gui/Panels/DirPickerPanel.cpp +++ b/pcsx2/gui/Panels/DirPickerPanel.cpp @@ -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 ); } diff --git a/pcsx2/gui/Panels/PluginSelectorPanel.cpp b/pcsx2/gui/Panels/PluginSelectorPanel.cpp index 719d902f8a..b008003da9 100644 --- a/pcsx2/gui/Panels/PluginSelectorPanel.cpp +++ b/pcsx2/gui/Panels/PluginSelectorPanel.cpp @@ -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; diff --git a/pcsx2/gui/Panels/ThemeSelectorPanel.cpp b/pcsx2/gui/Panels/ThemeSelectorPanel.cpp index e7a3ba01f5..6c9719b45d 100644 --- a/pcsx2/gui/Panels/ThemeSelectorPanel.cpp +++ b/pcsx2/gui/Panels/ThemeSelectorPanel.cpp @@ -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") );