diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 246c67086a..549e0abcf4 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -2524,36 +2524,6 @@ static void ChangeDescription( const RString &sNew ) pSteps->SetDescription(sNew); } -static bool ValidateDescription( const RString &sAnswer, RString &sErrorOut ) -{ - if( sAnswer.empty() ) - return true; - - /* Don't allow duplicate edit names within the same StepsType; edit names uniquely - * identify the edit. */ - Steps *pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; - Song *pSong = GAMESTATE->m_pCurSong; - if( pSteps->GetDifficulty() != DIFFICULTY_EDIT ) - return true; - - /* If unchanged: */ - if( pSteps->GetDescription() == sAnswer ) - return true; - - vector apSteps; - pSong->GetSteps( apSteps, pSteps->m_StepsType, DIFFICULTY_EDIT, -1, -1, sAnswer ); - - if( apSteps.size() == 0 ) - return true; - - /* The name is already used, */ - if( apSteps.size() > 1 ) - LOG->Warn( "Multiple edits for song \"%s\" named \"%s\"", pSong->GetSongDir().c_str(), sAnswer.c_str() ); - - sErrorOut = "The supplied name supplied conflicts with another edit.\n\nPlease use a different name."; - return false; -} - static void ChangeMainTitle( const RString &sNew ) { Song* pSong = GAMESTATE->m_pCurSong; @@ -3148,7 +3118,7 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v ENTER_NEW_DESCRIPTION, m_pSteps->GetDescription(), (dc == DIFFICULTY_EDIT) ? MAX_EDIT_STEPS_DESCRIPTION_LENGTH : 255, - ValidateDescription, + SongUtil::ValidateCurrentStepsDescription, ChangeDescription, NULL ); @@ -3156,10 +3126,10 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v } } -static LocalizedString ENTER_MAIN_TITLE ("ScreenEdit","Enter a new main title."); -static LocalizedString ENTER_SUB_TITLE ("ScreenEdit","Enter a new sub title."); -static LocalizedString ENTER_ARTIST ("ScreenEdit","Enter a new artist."); -static LocalizedString ENTER_CREDIT ("ScreenEdit","Enter a new credit."); +static LocalizedString ENTER_MAIN_TITLE ("ScreenEdit","Enter a new main title."); +static LocalizedString ENTER_SUB_TITLE ("ScreenEdit","Enter a new sub title."); +static LocalizedString ENTER_ARTIST ("ScreenEdit","Enter a new artist."); +static LocalizedString ENTER_CREDIT ("ScreenEdit","Enter a new credit."); static LocalizedString ENTER_MAIN_TITLE_TRANSLIT ("ScreenEdit","Enter a new main title transliteration."); static LocalizedString ENTER_SUB_TITLE_TRANSLIT ("ScreenEdit","Enter a new sub title transliteration."); static LocalizedString ENTER_ARTIST_TRANSLIT ("ScreenEdit","Enter a new artist transliteration."); diff --git a/stepmania/src/ScreenEditMenu.cpp b/stepmania/src/ScreenEditMenu.cpp index 75e49908cb..421a9df655 100644 --- a/stepmania/src/ScreenEditMenu.cpp +++ b/stepmania/src/ScreenEditMenu.cpp @@ -15,6 +15,7 @@ #include "ScreenTextEntry.h" #include "ScreenPrompt.h" #include "LocalizedString.h" +#include "SongUtil.h" #define EXPLANATION_TEXT( row ) THEME->GetString(m_sName,"Explanation"+EditMenuRowToString(row)) #define EDIT_MENU_TYPE THEME->GetMetric(m_sName,"EditMenuType") @@ -138,27 +139,6 @@ static RString GetCopyDescription( const Steps *pSourceSteps ) s = DifficultyToLocalizedString( pSourceSteps->GetDifficulty() ); return s; } - -static LocalizedString YOU_MUST_SUPPLY_NAME ( "ScreenEditMenu", "You must supply a name for your new edit." ); -static LocalizedString EDIT_NAME_CONFLICTS ( "ScreenEditMenu", "The name you chose conflicts with another edit. Please use a different name." ); -static bool ValidateCurrentStepsDescription( const RString &s, RString &sErrorOut ) -{ - ASSERT( GAMESTATE->m_pCurSteps[0]->GetDifficulty() == DIFFICULTY_EDIT ); - - if( s.empty() ) - { - sErrorOut = YOU_MUST_SUPPLY_NAME; - return false; - } - - if( !GAMESTATE->m_pCurSong->IsEditDescriptionUnique(GAMESTATE->m_pCurSteps[0]->m_StepsType, s, GAMESTATE->m_pCurSteps[0]) ) - { - sErrorOut = EDIT_NAME_CONFLICTS; - return false; - } - - return true; -} static void SetCurrentStepsDescription( const RString &s ) { @@ -258,7 +238,7 @@ void ScreenEditMenu::MenuStart( PlayerNumber pn ) } pSteps->SetDifficulty( dc ); // override difficulty with the user's choice - pSong->MakeUniqueEditDescription( st, sEditName ); + SongUtil::MakeUniqueEditDescription( pSong, st, sEditName ); pSteps->SetDescription( sEditName ); pSong->AddSteps( pSteps ); @@ -292,7 +272,7 @@ void ScreenEditMenu::MenuStart( PlayerNumber pn ) ENTER_EDIT_DESCRIPTION, GAMESTATE->m_pCurSteps[0]->GetDescription(), MAX_EDIT_STEPS_DESCRIPTION_LENGTH, - ValidateCurrentStepsDescription, + SongUtil::ValidateCurrentStepsDescription, SetCurrentStepsDescription, DeleteCurrentSteps ); } diff --git a/stepmania/src/ScreenOptionsManageEditSteps.cpp b/stepmania/src/ScreenOptionsManageEditSteps.cpp index c743d53c82..2c802fb1ce 100644 --- a/stepmania/src/ScreenOptionsManageEditSteps.cpp +++ b/stepmania/src/ScreenOptionsManageEditSteps.cpp @@ -13,6 +13,7 @@ #include "RageFileManager.h" #include "LocalizedString.h" #include "OptionRowHandler.h" +#include "SongUtil.h" AutoScreenMessage( SM_BackFromRename ) AutoScreenMessage( SM_BackFromDelete ) @@ -38,32 +39,6 @@ static MenuDef g_TempMenu( ); -static bool ValidateEditStepsDescription( const RString &sAnswer, RString &sErrorOut ) -{ - if( sAnswer.empty() ) - { - sErrorOut = "Description cannot be blank"; - return false; - } - - // Steps name must be unique - vector v; - SONGMAN->GetStepsLoadedFromProfile( v, ProfileSlot_Machine ); - FOREACH_CONST( Steps*, v, s ) - { - if( GAMESTATE->m_pCurSteps[PLAYER_1].Get() == *s ) - continue; // don't comepare name against ourself - - if( (*s)->GetDescription() == sAnswer ) - { - sErrorOut = "There is already another edit steps with this description. Each description must be unique."; - return false; - } - } - - return true; -} - REGISTER_SCREEN_CLASS( ScreenOptionsManageEditSteps ); @@ -98,7 +73,7 @@ void ScreenOptionsManageEditSteps::BeginScreen() OptionRowDefinition &def = vHands.back()->m_Def; def.m_sName = (*s)->GetDescription(); def.m_bAllowThemeTitle = false; // not themable - def.m_sExplanationName = "Edit Steps"; + def.m_sExplanationName = "Select Edit Steps"; def.m_vsChoices.clear(); RString sType = GAMEMAN->StepsTypeToLocalizedString( (*s)->m_StepsType ); def.m_vsChoices.push_back( sType ); @@ -199,7 +174,7 @@ void ScreenOptionsManageEditSteps::HandleScreenMessage( const ScreenMessage SM ) ENTER_NAME_FOR_STEPS, GAMESTATE->m_pCurSteps[PLAYER_1]->GetDescription(), MAX_EDIT_STEPS_DESCRIPTION_LENGTH, - ValidateEditStepsDescription ); + SongUtil::ValidateCurrentEditStepsDescription ); } break; case StepsEditAction_Delete: diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index b98e20bb44..76ae281117 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -1485,47 +1485,6 @@ float Song::GetStepsSeconds() const return GetElapsedTimeFromBeat( m_fLastBeat ) - GetElapsedTimeFromBeat( m_fFirstBeat ); } -bool Song::IsEditDescriptionUnique( StepsType st, RString sPreferredDescription, const Steps *pExclude ) const -{ - FOREACH_CONST( Steps*, m_vpSteps, s ) - { - Steps *pSteps = *s; - - if( pSteps->GetDifficulty() != DIFFICULTY_EDIT ) - continue; - if( pSteps->m_StepsType != st ) - continue; - if( pSteps == pExclude ) - continue; - if( pSteps->GetDescription() == sPreferredDescription ) - return false; - } - return true; -} - -void Song::MakeUniqueEditDescription( StepsType st, RString &sPreferredDescriptionInOut ) const -{ - if( IsEditDescriptionUnique( st, sPreferredDescriptionInOut, NULL ) ) - return; - - RString sTemp; - - for( int i=0; i<1000; i++ ) - { - // make name "My Edit" -> "My Edit2" - RString sNum = ssprintf("%d", i+1); - sTemp = sPreferredDescriptionInOut.Left( MAX_EDIT_STEPS_DESCRIPTION_LENGTH - sNum.size() ) + sNum; - - if( IsEditDescriptionUnique(st, sTemp, NULL) ) - { - sPreferredDescriptionInOut = sTemp; - return; - } - } - - // Edit limit guards should keep us from ever having more than 1000 edits per song. -} - // lua start #include "LuaBinding.h" diff --git a/stepmania/src/SongUtil.cpp b/stepmania/src/SongUtil.cpp index 4ffa00163d..ae359d02da 100644 --- a/stepmania/src/SongUtil.cpp +++ b/stepmania/src/SongUtil.cpp @@ -383,6 +383,105 @@ void SongUtil::SortByMostRecentlyPlayedForMachine( vector &vpSongsInOut ) g_mapSongSortVal.clear(); } +bool SongUtil::IsEditDescriptionUnique( const Song* pSong, StepsType st, const RString &sPreferredDescription, const Steps *pExclude ) +{ + FOREACH_CONST( Steps*, pSong->GetAllSteps(), s ) + { + Steps *pSteps = *s; + + if( pSteps->GetDifficulty() != DIFFICULTY_EDIT ) + continue; + if( pSteps->m_StepsType != st ) + continue; + if( pSteps == pExclude ) + continue; + if( pSteps->GetDescription() == sPreferredDescription ) + return false; + } + return true; +} + +RString SongUtil::MakeUniqueEditDescription( const Song *pSong, StepsType st, const RString &sPreferredDescription ) +{ + if( IsEditDescriptionUnique( pSong, st, sPreferredDescription, NULL ) ) + return sPreferredDescription; + + RString sTemp; + + for( int i=0; i<1000; i++ ) + { + // make name "My Edit" -> "My Edit2" + RString sNum = ssprintf("%d", i+1); + sTemp = sPreferredDescription.Left( MAX_EDIT_STEPS_DESCRIPTION_LENGTH - sNum.size() ) + sNum; + + if( IsEditDescriptionUnique(pSong, st, sTemp, NULL) ) + return sTemp; + } + + // Edit limit guards should keep us from ever having more than 1000 edits per song. + ASSERT(0); + return RString(); +} + +static LocalizedString YOU_MUST_SUPPLY_NAME ( "SongUtil", "You must supply a name for your new edit." ); +static LocalizedString EDIT_NAME_CONFLICTS ( "SongUtil", "The name you chose conflicts with another edit. Please use a different name." ); + +bool SongUtil::ValidateCurrentEditStepsDescription( const RString &sAnswer, RString &sErrorOut ) +{ + Steps *pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; + + ASSERT( pSteps->IsAnEdit() ); + + if( sAnswer.empty() ) + { + sErrorOut = YOU_MUST_SUPPLY_NAME; + return false; + } + + // Steps name must be unique + vector v; + SONGMAN->GetStepsLoadedFromProfile( v, ProfileSlot_Machine ); + FOREACH_CONST( Steps*, v, s ) + { + if( pSteps == *s ) + continue; // don't comepare name against ourself + + if( (*s)->GetDescription() == sAnswer ) + { + sErrorOut = EDIT_NAME_CONFLICTS; + return false; + } + } + + return true; +} + +bool SongUtil::ValidateCurrentStepsDescription( const RString &sAnswer, RString &sErrorOut ) +{ + if( sAnswer.empty() ) + return true; + + /* Don't allow duplicate edit names within the same StepsType; edit names uniquely + * identify the edit. */ + Steps *pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; + Song *pSong = GAMESTATE->m_pCurSong; + + + /* If unchanged: */ + if( pSteps->GetDescription() == sAnswer ) + return true; + + + if( pSteps->IsAnEdit() ) + { + return SongUtil::ValidateCurrentEditStepsDescription( sAnswer, sErrorOut ); + } + + return true; +} + + + ////////////////////////////////// // SongID ////////////////////////////////// diff --git a/stepmania/src/SongUtil.h b/stepmania/src/SongUtil.h index e36b0e0422..44daa02c38 100644 --- a/stepmania/src/SongUtil.h +++ b/stepmania/src/SongUtil.h @@ -7,6 +7,7 @@ #include "Difficulty.h" class Song; +class Steps; class Profile; class XNode; @@ -28,6 +29,11 @@ namespace SongUtil void SortByMostRecentlyPlayedForMachine( vector &vpSongsInOut ); int CompareSongPointersByGroup(const Song *pSong1, const Song *pSong2); + + bool IsEditDescriptionUnique( const Song* pSong, StepsType st, const RString &sPreferredDescription, const Steps *pExclude ); + RString MakeUniqueEditDescription( const Song* pSong, StepsType st, const RString &sPreferredDescription ); + bool ValidateCurrentEditStepsDescription( const RString &sAnswer, RString &sErrorOut ); + bool ValidateCurrentStepsDescription( const RString &sAnswer, RString &sErrorOut ); } class SongID diff --git a/stepmania/src/song.h b/stepmania/src/song.h index f50d5a0db2..068031f75d 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -229,9 +229,6 @@ public: int GetNumStepsLoadedFromProfile( ProfileSlot slot ) const; bool IsEditAlreadyLoaded( Steps* pSteps ) const; - bool IsEditDescriptionUnique( StepsType st, RString sPreferredDescription, const Steps *pExclude ) const; - void MakeUniqueEditDescription( StepsType st, RString &sPreferredDescriptionInOut ) const; - // An array of keysound file names (e.g. "beep.wav"). // The index in this array corresponds to the index in TapNote. If you // change the index in here, you must change all NoteData too.