From dd5480c69fae3fb12a250e5937065f9dfe8e75c3 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 30 Apr 2013 22:12:54 -0400 Subject: [PATCH] Few loops here. --- src/ScreenOptionsManageProfiles.cpp | 904 ++++++++++++++-------------- 1 file changed, 453 insertions(+), 451 deletions(-) diff --git a/src/ScreenOptionsManageProfiles.cpp b/src/ScreenOptionsManageProfiles.cpp index 7d312554c2..2a3a285321 100644 --- a/src/ScreenOptionsManageProfiles.cpp +++ b/src/ScreenOptionsManageProfiles.cpp @@ -1,451 +1,453 @@ -#include "global.h" -#include "ScreenOptionsManageProfiles.h" -#include "ScreenManager.h" -#include "RageLog.h" -#include "GameState.h" -#include "CommonMetrics.h" -#include "ScreenTextEntry.h" -#include "ScreenPrompt.h" -#include "ScreenMiniMenu.h" -#include "ProfileManager.h" -#include "Profile.h" -#include "OptionRowHandler.h" -#include "LocalizedString.h" - -static LocalizedString NEW_PROFILE_DEFAULT_NAME( "ScreenOptionsManageProfiles", "NewProfileDefaultName" ); - -#define SHOW_CREATE_NEW (!PROFILEMAN->FixedProfiles()) - -AutoScreenMessage( SM_BackFromEnterNameForNew ); -AutoScreenMessage( SM_BackFromRename ); -AutoScreenMessage( SM_BackFromDeleteConfirm ); -AutoScreenMessage( SM_BackFromClearConfirm ); -AutoScreenMessage( SM_BackFromContextMenu ); - -enum ProfileAction -{ - ProfileAction_SetDefaultP1, - ProfileAction_SetDefaultP2, - ProfileAction_Edit, - ProfileAction_Rename, - ProfileAction_Delete, - ProfileAction_Clear, - NUM_ProfileAction -}; -static const char *ProfileActionNames[] = { - "SetDefaultP1", - "SetDefaultP2", - "Edit", - "Rename", - "Delete", - "Clear", -}; -XToString( ProfileAction ); -XToLocalizedString( ProfileAction ); -/** @brief Loop through each ProfileAction. */ -#define FOREACH_ProfileAction( i ) FOREACH_ENUM( ProfileAction, i ) - -static MenuDef g_TempMenu( - "ScreenMiniMenuContext" -); - -static LocalizedString PROFILE_NAME_BLANK ( "ScreenEditMenu", "Profile name cannot be blank." ); -static LocalizedString PROFILE_NAME_CONFLICTS ( "ScreenEditMenu", "The name you chose conflicts with another profile. Please use a different name." ); -static bool ValidateLocalProfileName( const RString &sAnswer, RString &sErrorOut ) -{ - if( sAnswer == "" ) - { - sErrorOut = PROFILE_NAME_BLANK; - return false; - } - - Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); - if( pProfile != NULL && sAnswer == pProfile->m_sDisplayName ) - return true; // unchanged - - vector vsProfileNames; - PROFILEMAN->GetLocalProfileDisplayNames( vsProfileNames ); - bool bAlreadyAProfileWithThisName = find( vsProfileNames.begin(), vsProfileNames.end(), sAnswer ) != vsProfileNames.end(); - if( bAlreadyAProfileWithThisName ) - { - sErrorOut = PROFILE_NAME_CONFLICTS; - return false; - } - - return true; -} - -REGISTER_SCREEN_CLASS( ScreenOptionsManageProfiles ); - -void ScreenOptionsManageProfiles::Init() -{ - ScreenOptions::Init(); - - SetNavigation( NAV_THREE_KEY_MENU ); - SetInputMode( INPUTMODE_SHARE_CURSOR ); -} - -void ScreenOptionsManageProfiles::BeginScreen() -{ - // FIXME - // int iIndex = 0; - vector OptionRowHandlers; - - if( SHOW_CREATE_NEW ) - { - OptionRowHandler *pHand = OptionRowHandlerUtil::Make( ParseCommands(ssprintf("gamecommand;screen,%s;name,dummy",m_sName.c_str())) ); - OptionRowDefinition &def = pHand->m_Def; - def.m_layoutType = LAYOUT_SHOW_ALL_IN_ROW; - def.m_bAllowThemeTitle = true; - def.m_bAllowThemeItems = false; - def.m_sName = "Create New Profile"; - def.m_sExplanationName = "Create New Profile"; - OptionRowHandlers.push_back( pHand ); - - // FIXME - // gc.Load( iIndex++, ); - } - - PROFILEMAN->GetLocalProfileIDs( m_vsLocalProfileID ); - - FOREACH_CONST( RString, m_vsLocalProfileID, s ) - { - Profile *pProfile = PROFILEMAN->GetLocalProfile( *s ); - ASSERT( pProfile != NULL ); - - RString sCommand = ssprintf( "gamecommand;screen,ScreenOptionsEditProfile;profileid,%s;name,dummy", s->c_str() ); - OptionRowHandler *pHand = OptionRowHandlerUtil::Make( ParseCommands(sCommand) ); - OptionRowDefinition &def = pHand->m_Def; - def.m_layoutType = LAYOUT_SHOW_ALL_IN_ROW; - def.m_bAllowThemeTitle = false; - def.m_bAllowThemeItems = false; - def.m_sName = pProfile->m_sDisplayName; - def.m_sExplanationName = "Select Profile"; - - PlayerNumber pn = PLAYER_INVALID; - FOREACH_PlayerNumber( p ) - if( *s == ProfileManager::m_sDefaultLocalProfileID[p].Get() ) - pn = p; - if( pn != PLAYER_INVALID ) - def.m_vsChoices.push_back( PlayerNumberToLocalizedString(pn) ); - OptionRowHandlers.push_back( pHand ); - - // FIXME - // gc.Load( iIndex++, ); - } - - ScreenOptions::InitMenu( OptionRowHandlers ); - - // Save sEditLocalProfileID before calling ScreenOptions::BeginScreen, because it will get clobbered. - RString sEditLocalProfileID = GAMESTATE->m_sEditLocalProfileID; - - ScreenOptions::BeginScreen(); - - // select the last chosen profile - if( !sEditLocalProfileID.empty() ) - { - vector::const_iterator iter = find( m_vsLocalProfileID.begin(), m_vsLocalProfileID.end(), sEditLocalProfileID ); - if( iter != m_vsLocalProfileID.end() ) - { - int iIndex = iter - m_vsLocalProfileID.begin(); - this->MoveRowAbsolute( PLAYER_1, 1 + iIndex ); - } - } - else if( !m_vsLocalProfileID.empty() ) - { - // select the first item below "create new" - this->MoveRowAbsolute( PLAYER_1, 1 ); - } - - AfterChangeRow( PLAYER_1 ); -} - -static LocalizedString CONFIRM_DELETE_PROFILE ( "ScreenOptionsManageProfiles", "Are you sure you want to delete the profile '%s'?" ); -static LocalizedString CONFIRM_CLEAR_PROFILE ( "ScreenOptionsManageProfiles", "Are you sure you want to clear all data in the profile '%s'?" ); -static LocalizedString ENTER_PROFILE_NAME ( "ScreenOptionsManageProfiles", "Enter a name for the profile." ); -void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM ) -{ - if( SM == SM_GoToNextScreen ) - { - int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; - OptionRow &row = *m_pRows[iCurRow]; - if( row.GetRowType() == OptionRow::RowType_Exit ) - { - this->HandleScreenMessage( SM_GoToPrevScreen ); - return; // don't call base - } - } - else if( SM == SM_BackFromEnterNameForNew ) - { - if( !ScreenTextEntry::s_bCancelledLast ) - { - ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this - - RString sNewName = ScreenTextEntry::s_sLastAnswer; - ASSERT( GAMESTATE->m_sEditLocalProfileID.Get().empty() ); - - int iNumProfiles = PROFILEMAN->GetNumLocalProfiles(); - - // create - RString sProfileID; - - // is this the correct way to go about checking the return value? -aj - bool bCreateProfile = PROFILEMAN->CreateLocalProfile( ScreenTextEntry::s_sLastAnswer, sProfileID ); - ASSERT(bCreateProfile); - - GAMESTATE->m_sEditLocalProfileID.Set( sProfileID ); - - if( iNumProfiles < NUM_PLAYERS ) - { - int iFirstUnused = -1; - FOREACH_CONST( Preference*, PROFILEMAN->m_sDefaultLocalProfileID.m_v, i ) - { - RString sLocalProfileID = (*i)->Get(); - if( sLocalProfileID.empty() ) - { - iFirstUnused = i - PROFILEMAN->m_sDefaultLocalProfileID.m_v.begin(); - break; - } - } - if( iFirstUnused != -1 ) - { - PROFILEMAN->m_sDefaultLocalProfileID.m_v[iFirstUnused]->Set( sProfileID ); - } - } - - SCREENMAN->SetNewScreen( this->m_sName ); // reload - } - } - else if( SM == SM_BackFromRename ) - { - if( !ScreenTextEntry::s_bCancelledLast ) - { - ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this - - RString sNewName = ScreenTextEntry::s_sLastAnswer; - PROFILEMAN->RenameLocalProfile( GAMESTATE->m_sEditLocalProfileID, sNewName ); - - SCREENMAN->SetNewScreen( this->m_sName ); // reload - } - } - else if( SM == SM_BackFromDeleteConfirm ) - { - if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) - { - // Select the profile nearest to the one that was just deleted. - int iIndex = -1; - vector::const_iterator iter = find( m_vsLocalProfileID.begin(), m_vsLocalProfileID.end(), GAMESTATE->m_sEditLocalProfileID.Get() ); - if( iter != m_vsLocalProfileID.end() ) - iIndex = iter - m_vsLocalProfileID.begin(); - CLAMP( iIndex, 0, m_vsLocalProfileID.size()-1 ); - GAMESTATE->m_sEditLocalProfileID.Set( m_vsLocalProfileID[iIndex] ); - - PROFILEMAN->DeleteLocalProfile( GetLocalProfileIDWithFocus() ); - - SCREENMAN->SetNewScreen( this->m_sName ); // reload - } - } - else if( SM == SM_BackFromClearConfirm ) - { - if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) - { - GAMESTATE->GetEditLocalProfile()->InitAll(); - - SCREENMAN->SetNewScreen( this->m_sName ); // reload - } - } - else if( SM == SM_BackFromContextMenu ) - { - if( !ScreenMiniMenu::s_bCancelled ) - { - Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); - ASSERT( pProfile != NULL ); - - switch( ScreenMiniMenu::s_iLastRowCode ) - { - default: - FAIL_M(ssprintf("Last row code not a valid ProfileAction: %i", ScreenMiniMenu::s_iLastRowCode)); - case ProfileAction_SetDefaultP1: - case ProfileAction_SetDefaultP2: - { - FOREACH_PlayerNumber( p ) - if( ProfileManager::m_sDefaultLocalProfileID[p].Get() == GetLocalProfileIDWithFocus() ) - ProfileManager::m_sDefaultLocalProfileID[p].Set(""); - - PlayerNumber pn = (PlayerNumber)(ScreenMiniMenu::s_iLastRowCode - ProfileAction_SetDefaultP1); - ProfileManager::m_sDefaultLocalProfileID[pn].Set( GetLocalProfileIDWithFocus() ); - - SCREENMAN->SetNewScreen( this->m_sName ); // reload - } - break; - case ProfileAction_Edit: - { - GAMESTATE->m_sEditLocalProfileID.Set( GetLocalProfileIDWithFocus() ); - - ScreenOptions::BeginFadingOut(); - } - break; - case ProfileAction_Rename: - { - ScreenTextEntry::TextEntry( - SM_BackFromRename, - ENTER_PROFILE_NAME, - pProfile->m_sDisplayName, - PROFILE_MAX_DISPLAY_NAME_LENGTH, - ValidateLocalProfileName ); - } - break; - case ProfileAction_Delete: - { - RString sTitle = pProfile->m_sDisplayName; - RString sMessage = ssprintf( CONFIRM_DELETE_PROFILE.GetValue(), sTitle.c_str() ); - ScreenPrompt::Prompt( SM_BackFromDeleteConfirm, sMessage, PROMPT_YES_NO ); - } - break; - case ProfileAction_Clear: - { - RString sTitle = pProfile->m_sDisplayName; - RString sMessage = ssprintf( CONFIRM_CLEAR_PROFILE.GetValue(), sTitle.c_str() ); - ScreenPrompt::Prompt( SM_BackFromClearConfirm, sMessage, PROMPT_YES_NO ); - } - break; - } - } - } - else if( SM == SM_LoseFocus ) - { - this->PlayCommand( "ScreenLoseFocus" ); - } - else if( SM == SM_GainFocus ) - { - this->PlayCommand( "ScreenGainFocus" ); - } - - ScreenOptions::HandleScreenMessage( SM ); -} - -void ScreenOptionsManageProfiles::AfterChangeRow( PlayerNumber pn ) -{ - GAMESTATE->m_sEditLocalProfileID.Set( GetLocalProfileIDWithFocus() ); - - ScreenOptions::AfterChangeRow( pn ); -} - -void ScreenOptionsManageProfiles::ProcessMenuStart( const InputEventPlus & ) -{ - if( IsTransitioning() ) - return; - - int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; - OptionRow &row = *m_pRows[iCurRow]; - - if( SHOW_CREATE_NEW && iCurRow == 0 ) // "create new" - { - vector vsUsedNames; - PROFILEMAN->GetLocalProfileDisplayNames( vsUsedNames ); - - RString sPotentialName; - for( int i=1; i<1000; i++ ) - { - sPotentialName = ssprintf( "%s%04d", NEW_PROFILE_DEFAULT_NAME.GetValue().c_str(), i ); - bool bNameIsUsed = find( vsUsedNames.begin(), vsUsedNames.end(), sPotentialName ) != vsUsedNames.end(); - if( !bNameIsUsed ) - break; - } - ScreenTextEntry::TextEntry( - SM_BackFromEnterNameForNew, - ENTER_PROFILE_NAME, - sPotentialName, - PROFILE_MAX_DISPLAY_NAME_LENGTH, - ValidateLocalProfileName ); - } - else if( row.GetRowType() == OptionRow::RowType_Exit ) - { - SCREENMAN->PlayStartSound(); - this->BeginFadingOut(); - } - else // a profile - { - g_TempMenu.rows.clear(); - -#define ADD_ACTION( i ) \ - g_TempMenu.rows.push_back( MenuRowDef( i, ProfileActionToLocalizedString(i), true, EditMode_Home, false, false, 0, "" ) ); - - ADD_ACTION( ProfileAction_SetDefaultP1 ); - ADD_ACTION( ProfileAction_SetDefaultP2 ); - if( PROFILEMAN->FixedProfiles() ) - { - ADD_ACTION( ProfileAction_Rename ); - ADD_ACTION( ProfileAction_Clear ); - } - else - { - //ADD_ACTION( ProfileAction_Edit ); - ADD_ACTION( ProfileAction_Rename ); - ADD_ACTION( ProfileAction_Delete ); - } - - int iWidth, iX, iY; - this->GetWidthXY( PLAYER_1, iCurRow, 0, iWidth, iX, iY ); - - ScreenMiniMenu::MiniMenu( &g_TempMenu, SM_BackFromContextMenu, SM_BackFromContextMenu, (float)iX, (float)iY ); - } -} - -void ScreenOptionsManageProfiles::ImportOptions( int /* iRow */, const vector & /* vpns */ ) -{ - -} - -void ScreenOptionsManageProfiles::ExportOptions( int /* iRow */, const vector & /* vpns */ ) -{ - -} - -int ScreenOptionsManageProfiles::GetLocalProfileIndexWithFocus() const -{ - int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; - OptionRow &row = *m_pRows[iCurRow]; - - if( SHOW_CREATE_NEW && iCurRow == 0 ) // "create new" - return -1; - else if( row.GetRowType() == OptionRow::RowType_Exit ) - return -1; - - // a profile - int iIndex = iCurRow + (SHOW_CREATE_NEW ? -1 : 0); - return iIndex; -} - -RString ScreenOptionsManageProfiles::GetLocalProfileIDWithFocus() const -{ - int iIndex = GetLocalProfileIndexWithFocus(); - if( iIndex == -1 ) - return RString(); - return m_vsLocalProfileID[iIndex]; -} - -/* - * (c) 2002-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "ScreenOptionsManageProfiles.h" +#include "ScreenManager.h" +#include "RageLog.h" +#include "GameState.h" +#include "CommonMetrics.h" +#include "ScreenTextEntry.h" +#include "ScreenPrompt.h" +#include "ScreenMiniMenu.h" +#include "ProfileManager.h" +#include "Profile.h" +#include "OptionRowHandler.h" +#include "LocalizedString.h" + +static LocalizedString NEW_PROFILE_DEFAULT_NAME( "ScreenOptionsManageProfiles", "NewProfileDefaultName" ); + +#define SHOW_CREATE_NEW (!PROFILEMAN->FixedProfiles()) + +AutoScreenMessage( SM_BackFromEnterNameForNew ); +AutoScreenMessage( SM_BackFromRename ); +AutoScreenMessage( SM_BackFromDeleteConfirm ); +AutoScreenMessage( SM_BackFromClearConfirm ); +AutoScreenMessage( SM_BackFromContextMenu ); + +enum ProfileAction +{ + ProfileAction_SetDefaultP1, + ProfileAction_SetDefaultP2, + ProfileAction_Edit, + ProfileAction_Rename, + ProfileAction_Delete, + ProfileAction_Clear, + NUM_ProfileAction +}; +static const char *ProfileActionNames[] = { + "SetDefaultP1", + "SetDefaultP2", + "Edit", + "Rename", + "Delete", + "Clear", +}; +XToString( ProfileAction ); +XToLocalizedString( ProfileAction ); +/** @brief Loop through each ProfileAction. */ +#define FOREACH_ProfileAction( i ) FOREACH_ENUM( ProfileAction, i ) + +static MenuDef g_TempMenu( + "ScreenMiniMenuContext" +); + +static LocalizedString PROFILE_NAME_BLANK ( "ScreenEditMenu", "Profile name cannot be blank." ); +static LocalizedString PROFILE_NAME_CONFLICTS ( "ScreenEditMenu", "The name you chose conflicts with another profile. Please use a different name." ); +static bool ValidateLocalProfileName( const RString &sAnswer, RString &sErrorOut ) +{ + if( sAnswer == "" ) + { + sErrorOut = PROFILE_NAME_BLANK; + return false; + } + + Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); + if( pProfile != NULL && sAnswer == pProfile->m_sDisplayName ) + return true; // unchanged + + vector vsProfileNames; + PROFILEMAN->GetLocalProfileDisplayNames( vsProfileNames ); + bool bAlreadyAProfileWithThisName = find( vsProfileNames.begin(), vsProfileNames.end(), sAnswer ) != vsProfileNames.end(); + if( bAlreadyAProfileWithThisName ) + { + sErrorOut = PROFILE_NAME_CONFLICTS; + return false; + } + + return true; +} + +REGISTER_SCREEN_CLASS( ScreenOptionsManageProfiles ); + +void ScreenOptionsManageProfiles::Init() +{ + ScreenOptions::Init(); + + SetNavigation( NAV_THREE_KEY_MENU ); + SetInputMode( INPUTMODE_SHARE_CURSOR ); +} + +void ScreenOptionsManageProfiles::BeginScreen() +{ + // FIXME + // int iIndex = 0; + vector OptionRowHandlers; + + if( SHOW_CREATE_NEW ) + { + OptionRowHandler *pHand = OptionRowHandlerUtil::Make( ParseCommands(ssprintf("gamecommand;screen,%s;name,dummy",m_sName.c_str())) ); + OptionRowDefinition &def = pHand->m_Def; + def.m_layoutType = LAYOUT_SHOW_ALL_IN_ROW; + def.m_bAllowThemeTitle = true; + def.m_bAllowThemeItems = false; + def.m_sName = "Create New Profile"; + def.m_sExplanationName = "Create New Profile"; + OptionRowHandlers.push_back( pHand ); + + // FIXME + // gc.Load( iIndex++, ); + } + + PROFILEMAN->GetLocalProfileIDs( m_vsLocalProfileID ); + + for (RString const &s : m_vsLocalProfileID) + { + Profile *pProfile = PROFILEMAN->GetLocalProfile( s ); + ASSERT( pProfile != NULL ); + + RString sCommand = ssprintf( "gamecommand;screen,ScreenOptionsEditProfile;profileid,%s;name,dummy", s.c_str() ); + OptionRowHandler *pHand = OptionRowHandlerUtil::Make( ParseCommands(sCommand) ); + OptionRowDefinition &def = pHand->m_Def; + def.m_layoutType = LAYOUT_SHOW_ALL_IN_ROW; + def.m_bAllowThemeTitle = false; + def.m_bAllowThemeItems = false; + def.m_sName = pProfile->m_sDisplayName; + def.m_sExplanationName = "Select Profile"; + + PlayerNumber pn = PLAYER_INVALID; + FOREACH_PlayerNumber( p ) + if( s == ProfileManager::m_sDefaultLocalProfileID[p].Get() ) + pn = p; + if( pn != PLAYER_INVALID ) + def.m_vsChoices.push_back( PlayerNumberToLocalizedString(pn) ); + OptionRowHandlers.push_back( pHand ); + + // FIXME + // gc.Load( iIndex++, ); + } + + ScreenOptions::InitMenu( OptionRowHandlers ); + + // Save sEditLocalProfileID before calling ScreenOptions::BeginScreen, because it will get clobbered. + RString sEditLocalProfileID = GAMESTATE->m_sEditLocalProfileID; + + ScreenOptions::BeginScreen(); + + // select the last chosen profile + if( !sEditLocalProfileID.empty() ) + { + vector::const_iterator iter = find( m_vsLocalProfileID.begin(), m_vsLocalProfileID.end(), sEditLocalProfileID ); + if( iter != m_vsLocalProfileID.end() ) + { + int iIndex = iter - m_vsLocalProfileID.begin(); + this->MoveRowAbsolute( PLAYER_1, 1 + iIndex ); + } + } + else if( !m_vsLocalProfileID.empty() ) + { + // select the first item below "create new" + this->MoveRowAbsolute( PLAYER_1, 1 ); + } + + AfterChangeRow( PLAYER_1 ); +} + +static LocalizedString CONFIRM_DELETE_PROFILE ( "ScreenOptionsManageProfiles", "Are you sure you want to delete the profile '%s'?" ); +static LocalizedString CONFIRM_CLEAR_PROFILE ( "ScreenOptionsManageProfiles", "Are you sure you want to clear all data in the profile '%s'?" ); +static LocalizedString ENTER_PROFILE_NAME ( "ScreenOptionsManageProfiles", "Enter a name for the profile." ); +void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM ) +{ + if( SM == SM_GoToNextScreen ) + { + int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; + OptionRow &row = *m_pRows[iCurRow]; + if( row.GetRowType() == OptionRow::RowType_Exit ) + { + this->HandleScreenMessage( SM_GoToPrevScreen ); + return; // don't call base + } + } + else if( SM == SM_BackFromEnterNameForNew ) + { + if( !ScreenTextEntry::s_bCancelledLast ) + { + ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this + + RString sNewName = ScreenTextEntry::s_sLastAnswer; + ASSERT( GAMESTATE->m_sEditLocalProfileID.Get().empty() ); + + int iNumProfiles = PROFILEMAN->GetNumLocalProfiles(); + + // create + RString sProfileID; + + // is this the correct way to go about checking the return value? -aj + bool bCreateProfile = PROFILEMAN->CreateLocalProfile( ScreenTextEntry::s_sLastAnswer, sProfileID ); + ASSERT(bCreateProfile); + + GAMESTATE->m_sEditLocalProfileID.Set( sProfileID ); + + if( iNumProfiles < NUM_PLAYERS ) + { + int iFirstUnused = -1; + int index = 0; + for (Preference const *i : PROFILEMAN->m_sDefaultLocalProfileID.m_v) + { + RString sLocalProfileID = i->Get(); + if( sLocalProfileID.empty() ) + { + iFirstUnused = index; + break; + } + ++index; + } + if( iFirstUnused != -1 ) + { + PROFILEMAN->m_sDefaultLocalProfileID.m_v[iFirstUnused]->Set( sProfileID ); + } + } + + SCREENMAN->SetNewScreen( this->m_sName ); // reload + } + } + else if( SM == SM_BackFromRename ) + { + if( !ScreenTextEntry::s_bCancelledLast ) + { + ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this + + RString sNewName = ScreenTextEntry::s_sLastAnswer; + PROFILEMAN->RenameLocalProfile( GAMESTATE->m_sEditLocalProfileID, sNewName ); + + SCREENMAN->SetNewScreen( this->m_sName ); // reload + } + } + else if( SM == SM_BackFromDeleteConfirm ) + { + if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) + { + // Select the profile nearest to the one that was just deleted. + int iIndex = -1; + vector::const_iterator iter = find( m_vsLocalProfileID.begin(), m_vsLocalProfileID.end(), GAMESTATE->m_sEditLocalProfileID.Get() ); + if( iter != m_vsLocalProfileID.end() ) + iIndex = iter - m_vsLocalProfileID.begin(); + CLAMP( iIndex, 0, m_vsLocalProfileID.size()-1 ); + GAMESTATE->m_sEditLocalProfileID.Set( m_vsLocalProfileID[iIndex] ); + + PROFILEMAN->DeleteLocalProfile( GetLocalProfileIDWithFocus() ); + + SCREENMAN->SetNewScreen( this->m_sName ); // reload + } + } + else if( SM == SM_BackFromClearConfirm ) + { + if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) + { + GAMESTATE->GetEditLocalProfile()->InitAll(); + + SCREENMAN->SetNewScreen( this->m_sName ); // reload + } + } + else if( SM == SM_BackFromContextMenu ) + { + if( !ScreenMiniMenu::s_bCancelled ) + { + Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); + ASSERT( pProfile != NULL ); + + switch( ScreenMiniMenu::s_iLastRowCode ) + { + default: + FAIL_M(ssprintf("Last row code not a valid ProfileAction: %i", ScreenMiniMenu::s_iLastRowCode)); + case ProfileAction_SetDefaultP1: + case ProfileAction_SetDefaultP2: + { + FOREACH_PlayerNumber( p ) + if( ProfileManager::m_sDefaultLocalProfileID[p].Get() == GetLocalProfileIDWithFocus() ) + ProfileManager::m_sDefaultLocalProfileID[p].Set(""); + + PlayerNumber pn = (PlayerNumber)(ScreenMiniMenu::s_iLastRowCode - ProfileAction_SetDefaultP1); + ProfileManager::m_sDefaultLocalProfileID[pn].Set( GetLocalProfileIDWithFocus() ); + + SCREENMAN->SetNewScreen( this->m_sName ); // reload + } + break; + case ProfileAction_Edit: + { + GAMESTATE->m_sEditLocalProfileID.Set( GetLocalProfileIDWithFocus() ); + + ScreenOptions::BeginFadingOut(); + } + break; + case ProfileAction_Rename: + { + ScreenTextEntry::TextEntry( + SM_BackFromRename, + ENTER_PROFILE_NAME, + pProfile->m_sDisplayName, + PROFILE_MAX_DISPLAY_NAME_LENGTH, + ValidateLocalProfileName ); + } + break; + case ProfileAction_Delete: + { + RString sTitle = pProfile->m_sDisplayName; + RString sMessage = ssprintf( CONFIRM_DELETE_PROFILE.GetValue(), sTitle.c_str() ); + ScreenPrompt::Prompt( SM_BackFromDeleteConfirm, sMessage, PROMPT_YES_NO ); + } + break; + case ProfileAction_Clear: + { + RString sTitle = pProfile->m_sDisplayName; + RString sMessage = ssprintf( CONFIRM_CLEAR_PROFILE.GetValue(), sTitle.c_str() ); + ScreenPrompt::Prompt( SM_BackFromClearConfirm, sMessage, PROMPT_YES_NO ); + } + break; + } + } + } + else if( SM == SM_LoseFocus ) + { + this->PlayCommand( "ScreenLoseFocus" ); + } + else if( SM == SM_GainFocus ) + { + this->PlayCommand( "ScreenGainFocus" ); + } + + ScreenOptions::HandleScreenMessage( SM ); +} + +void ScreenOptionsManageProfiles::AfterChangeRow( PlayerNumber pn ) +{ + GAMESTATE->m_sEditLocalProfileID.Set( GetLocalProfileIDWithFocus() ); + + ScreenOptions::AfterChangeRow( pn ); +} + +void ScreenOptionsManageProfiles::ProcessMenuStart( const InputEventPlus & ) +{ + if( IsTransitioning() ) + return; + + int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; + OptionRow &row = *m_pRows[iCurRow]; + + if( SHOW_CREATE_NEW && iCurRow == 0 ) // "create new" + { + vector vsUsedNames; + PROFILEMAN->GetLocalProfileDisplayNames( vsUsedNames ); + + RString sPotentialName; + for( int i=1; i<1000; i++ ) + { + sPotentialName = ssprintf( "%s%04d", NEW_PROFILE_DEFAULT_NAME.GetValue().c_str(), i ); + bool bNameIsUsed = find( vsUsedNames.begin(), vsUsedNames.end(), sPotentialName ) != vsUsedNames.end(); + if( !bNameIsUsed ) + break; + } + ScreenTextEntry::TextEntry( + SM_BackFromEnterNameForNew, + ENTER_PROFILE_NAME, + sPotentialName, + PROFILE_MAX_DISPLAY_NAME_LENGTH, + ValidateLocalProfileName ); + } + else if( row.GetRowType() == OptionRow::RowType_Exit ) + { + SCREENMAN->PlayStartSound(); + this->BeginFadingOut(); + } + else // a profile + { + g_TempMenu.rows.clear(); + +#define ADD_ACTION( i ) \ + g_TempMenu.rows.push_back( MenuRowDef( i, ProfileActionToLocalizedString(i), true, EditMode_Home, false, false, 0, "" ) ); + + ADD_ACTION( ProfileAction_SetDefaultP1 ); + ADD_ACTION( ProfileAction_SetDefaultP2 ); + if( PROFILEMAN->FixedProfiles() ) + { + ADD_ACTION( ProfileAction_Rename ); + ADD_ACTION( ProfileAction_Clear ); + } + else + { + //ADD_ACTION( ProfileAction_Edit ); + ADD_ACTION( ProfileAction_Rename ); + ADD_ACTION( ProfileAction_Delete ); + } + + int iWidth, iX, iY; + this->GetWidthXY( PLAYER_1, iCurRow, 0, iWidth, iX, iY ); + + ScreenMiniMenu::MiniMenu( &g_TempMenu, SM_BackFromContextMenu, SM_BackFromContextMenu, (float)iX, (float)iY ); + } +} + +void ScreenOptionsManageProfiles::ImportOptions( int /* iRow */, const vector & /* vpns */ ) +{ + +} + +void ScreenOptionsManageProfiles::ExportOptions( int /* iRow */, const vector & /* vpns */ ) +{ + +} + +int ScreenOptionsManageProfiles::GetLocalProfileIndexWithFocus() const +{ + int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; + OptionRow &row = *m_pRows[iCurRow]; + + if( SHOW_CREATE_NEW && iCurRow == 0 ) // "create new" + return -1; + else if( row.GetRowType() == OptionRow::RowType_Exit ) + return -1; + + // a profile + int iIndex = iCurRow + (SHOW_CREATE_NEW ? -1 : 0); + return iIndex; +} + +RString ScreenOptionsManageProfiles::GetLocalProfileIDWithFocus() const +{ + int iIndex = GetLocalProfileIndexWithFocus(); + if( iIndex == -1 ) + return RString(); + return m_vsLocalProfileID[iIndex]; +} + +/* + * (c) 2002-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */