consolidate Steps description validation
This commit is contained in:
@@ -2524,36 +2524,6 @@ static void ChangeDescription( const RString &sNew )
|
|||||||
pSteps->SetDescription(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<Steps*> 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 )
|
static void ChangeMainTitle( const RString &sNew )
|
||||||
{
|
{
|
||||||
Song* pSong = GAMESTATE->m_pCurSong;
|
Song* pSong = GAMESTATE->m_pCurSong;
|
||||||
@@ -3148,7 +3118,7 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v
|
|||||||
ENTER_NEW_DESCRIPTION,
|
ENTER_NEW_DESCRIPTION,
|
||||||
m_pSteps->GetDescription(),
|
m_pSteps->GetDescription(),
|
||||||
(dc == DIFFICULTY_EDIT) ? MAX_EDIT_STEPS_DESCRIPTION_LENGTH : 255,
|
(dc == DIFFICULTY_EDIT) ? MAX_EDIT_STEPS_DESCRIPTION_LENGTH : 255,
|
||||||
ValidateDescription,
|
SongUtil::ValidateCurrentStepsDescription,
|
||||||
ChangeDescription,
|
ChangeDescription,
|
||||||
NULL
|
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_MAIN_TITLE ("ScreenEdit","Enter a new main title.");
|
||||||
static LocalizedString ENTER_SUB_TITLE ("ScreenEdit","Enter a new sub title.");
|
static LocalizedString ENTER_SUB_TITLE ("ScreenEdit","Enter a new sub title.");
|
||||||
static LocalizedString ENTER_ARTIST ("ScreenEdit","Enter a new artist.");
|
static LocalizedString ENTER_ARTIST ("ScreenEdit","Enter a new artist.");
|
||||||
static LocalizedString ENTER_CREDIT ("ScreenEdit","Enter a new credit.");
|
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_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_SUB_TITLE_TRANSLIT ("ScreenEdit","Enter a new sub title transliteration.");
|
||||||
static LocalizedString ENTER_ARTIST_TRANSLIT ("ScreenEdit","Enter a new artist transliteration.");
|
static LocalizedString ENTER_ARTIST_TRANSLIT ("ScreenEdit","Enter a new artist transliteration.");
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "ScreenTextEntry.h"
|
#include "ScreenTextEntry.h"
|
||||||
#include "ScreenPrompt.h"
|
#include "ScreenPrompt.h"
|
||||||
#include "LocalizedString.h"
|
#include "LocalizedString.h"
|
||||||
|
#include "SongUtil.h"
|
||||||
|
|
||||||
#define EXPLANATION_TEXT( row ) THEME->GetString(m_sName,"Explanation"+EditMenuRowToString(row))
|
#define EXPLANATION_TEXT( row ) THEME->GetString(m_sName,"Explanation"+EditMenuRowToString(row))
|
||||||
#define EDIT_MENU_TYPE THEME->GetMetric(m_sName,"EditMenuType")
|
#define EDIT_MENU_TYPE THEME->GetMetric(m_sName,"EditMenuType")
|
||||||
@@ -139,27 +140,6 @@ static RString GetCopyDescription( const Steps *pSourceSteps )
|
|||||||
return s;
|
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 )
|
static void SetCurrentStepsDescription( const RString &s )
|
||||||
{
|
{
|
||||||
GAMESTATE->m_pCurSteps[0]->SetDescription( s );
|
GAMESTATE->m_pCurSteps[0]->SetDescription( s );
|
||||||
@@ -258,7 +238,7 @@ void ScreenEditMenu::MenuStart( PlayerNumber pn )
|
|||||||
}
|
}
|
||||||
|
|
||||||
pSteps->SetDifficulty( dc ); // override difficulty with the user's choice
|
pSteps->SetDifficulty( dc ); // override difficulty with the user's choice
|
||||||
pSong->MakeUniqueEditDescription( st, sEditName );
|
SongUtil::MakeUniqueEditDescription( pSong, st, sEditName );
|
||||||
pSteps->SetDescription( sEditName );
|
pSteps->SetDescription( sEditName );
|
||||||
pSong->AddSteps( pSteps );
|
pSong->AddSteps( pSteps );
|
||||||
|
|
||||||
@@ -292,7 +272,7 @@ void ScreenEditMenu::MenuStart( PlayerNumber pn )
|
|||||||
ENTER_EDIT_DESCRIPTION,
|
ENTER_EDIT_DESCRIPTION,
|
||||||
GAMESTATE->m_pCurSteps[0]->GetDescription(),
|
GAMESTATE->m_pCurSteps[0]->GetDescription(),
|
||||||
MAX_EDIT_STEPS_DESCRIPTION_LENGTH,
|
MAX_EDIT_STEPS_DESCRIPTION_LENGTH,
|
||||||
ValidateCurrentStepsDescription,
|
SongUtil::ValidateCurrentStepsDescription,
|
||||||
SetCurrentStepsDescription,
|
SetCurrentStepsDescription,
|
||||||
DeleteCurrentSteps );
|
DeleteCurrentSteps );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "RageFileManager.h"
|
#include "RageFileManager.h"
|
||||||
#include "LocalizedString.h"
|
#include "LocalizedString.h"
|
||||||
#include "OptionRowHandler.h"
|
#include "OptionRowHandler.h"
|
||||||
|
#include "SongUtil.h"
|
||||||
|
|
||||||
AutoScreenMessage( SM_BackFromRename )
|
AutoScreenMessage( SM_BackFromRename )
|
||||||
AutoScreenMessage( SM_BackFromDelete )
|
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<Steps*> 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 );
|
REGISTER_SCREEN_CLASS( ScreenOptionsManageEditSteps );
|
||||||
|
|
||||||
@@ -98,7 +73,7 @@ void ScreenOptionsManageEditSteps::BeginScreen()
|
|||||||
OptionRowDefinition &def = vHands.back()->m_Def;
|
OptionRowDefinition &def = vHands.back()->m_Def;
|
||||||
def.m_sName = (*s)->GetDescription();
|
def.m_sName = (*s)->GetDescription();
|
||||||
def.m_bAllowThemeTitle = false; // not themable
|
def.m_bAllowThemeTitle = false; // not themable
|
||||||
def.m_sExplanationName = "Edit Steps";
|
def.m_sExplanationName = "Select Edit Steps";
|
||||||
def.m_vsChoices.clear();
|
def.m_vsChoices.clear();
|
||||||
RString sType = GAMEMAN->StepsTypeToLocalizedString( (*s)->m_StepsType );
|
RString sType = GAMEMAN->StepsTypeToLocalizedString( (*s)->m_StepsType );
|
||||||
def.m_vsChoices.push_back( sType );
|
def.m_vsChoices.push_back( sType );
|
||||||
@@ -199,7 +174,7 @@ void ScreenOptionsManageEditSteps::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
ENTER_NAME_FOR_STEPS,
|
ENTER_NAME_FOR_STEPS,
|
||||||
GAMESTATE->m_pCurSteps[PLAYER_1]->GetDescription(),
|
GAMESTATE->m_pCurSteps[PLAYER_1]->GetDescription(),
|
||||||
MAX_EDIT_STEPS_DESCRIPTION_LENGTH,
|
MAX_EDIT_STEPS_DESCRIPTION_LENGTH,
|
||||||
ValidateEditStepsDescription );
|
SongUtil::ValidateCurrentEditStepsDescription );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case StepsEditAction_Delete:
|
case StepsEditAction_Delete:
|
||||||
|
|||||||
@@ -1485,47 +1485,6 @@ float Song::GetStepsSeconds() const
|
|||||||
return GetElapsedTimeFromBeat( m_fLastBeat ) - GetElapsedTimeFromBeat( m_fFirstBeat );
|
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
|
// lua start
|
||||||
#include "LuaBinding.h"
|
#include "LuaBinding.h"
|
||||||
|
|||||||
@@ -383,6 +383,105 @@ void SongUtil::SortByMostRecentlyPlayedForMachine( vector<Song*> &vpSongsInOut )
|
|||||||
g_mapSongSortVal.clear();
|
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<Steps*> 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
|
// SongID
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "Difficulty.h"
|
#include "Difficulty.h"
|
||||||
|
|
||||||
class Song;
|
class Song;
|
||||||
|
class Steps;
|
||||||
class Profile;
|
class Profile;
|
||||||
class XNode;
|
class XNode;
|
||||||
|
|
||||||
@@ -28,6 +29,11 @@ namespace SongUtil
|
|||||||
void SortByMostRecentlyPlayedForMachine( vector<Song*> &vpSongsInOut );
|
void SortByMostRecentlyPlayedForMachine( vector<Song*> &vpSongsInOut );
|
||||||
|
|
||||||
int CompareSongPointersByGroup(const Song *pSong1, const Song *pSong2);
|
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
|
class SongID
|
||||||
|
|||||||
@@ -229,9 +229,6 @@ public:
|
|||||||
int GetNumStepsLoadedFromProfile( ProfileSlot slot ) const;
|
int GetNumStepsLoadedFromProfile( ProfileSlot slot ) const;
|
||||||
bool IsEditAlreadyLoaded( Steps* pSteps ) 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").
|
// An array of keysound file names (e.g. "beep.wav").
|
||||||
// The index in this array corresponds to the index in TapNote. If you
|
// The index in this array corresponds to the index in TapNote. If you
|
||||||
// change the index in here, you must change all NoteData too.
|
// change the index in here, you must change all NoteData too.
|
||||||
|
|||||||
Reference in New Issue
Block a user