finish edit renaming and handle display errors encountered during rename
This commit is contained in:
@@ -1147,6 +1147,10 @@ These steps will be lost permanently.=These steps will be lost permanently.
|
||||
You have %d step edits, the maximum number allowed.=You have %d step edits, the maximum number allowed.
|
||||
You must delete an existing steps edit before creating a new steps edit.=You must delete an existing steps edit before creating a new steps edit.
|
||||
|
||||
[NotesWriterSM]
|
||||
Error renaming file. Destination file '%s' already exists.=Error renaming file. Destination file '%s' already exists.
|
||||
Error writing file '%s'.=Error writing file '%s'.
|
||||
|
||||
[ScreenOptionsManageProfiles]
|
||||
Are you sure you want to clear all data in the profile '%s'?=Are you sure you want to clear all data in the profile '%s'?
|
||||
Are you sure you want to delete the profile '%s'?=Are you sure you want to delete the profile '%s'?
|
||||
@@ -1348,6 +1352,7 @@ The folder '%s' appears to be a song folder. All song folders must reside in a
|
||||
[SongUtil]
|
||||
You must supply a name for your new edit.=You must supply a name for your new edit.
|
||||
The name you chose conflicts with another edit. Please use a different name.=The name you chose conflicts with another edit. Please use a different name.
|
||||
The edit name cannot contain any of the following characters: %s=The edit name cannot contain any of the following characters: %s
|
||||
|
||||
[SongSort]
|
||||
FewestPlays=Fewest Plays
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "BackgroundUtil.h"
|
||||
#include "ProfileManager.h"
|
||||
#include "Profile.h"
|
||||
#include "LocalizedString.h"
|
||||
|
||||
static RString BackgroundChangeToString( const BackgroundChange &bgc )
|
||||
{
|
||||
@@ -272,7 +273,9 @@ RString NotesWriterSM::GetEditFileName( const Song *pSong, const Steps *pSteps )
|
||||
return sFile;
|
||||
}
|
||||
|
||||
bool NotesWriterSM::WriteEditFileToMachine( const Song *pSong, Steps *pSteps )
|
||||
static LocalizedString DESTINATION_ALREADY_EXISTS ("NotesWriterSM", "Error renaming file. Destination file '%s' already exists.");
|
||||
static LocalizedString ERROR_WRITING_FILE ("NotesWriterSM", "Error writing file '%s'.");
|
||||
bool NotesWriterSM::WriteEditFileToMachine( const Song *pSong, Steps *pSteps, RString &sErrorOut )
|
||||
{
|
||||
RString sDir = PROFILEMAN->GetProfileDir( ProfileSlot_Machine ) + EDIT_STEPS_SUBDIR;
|
||||
|
||||
@@ -281,12 +284,20 @@ bool NotesWriterSM::WriteEditFileToMachine( const Song *pSong, Steps *pSteps )
|
||||
/* Flush dir cache when writing steps, so the old size isn't cached. */
|
||||
FILEMAN->FlushDirCache( Dirname(sPath) );
|
||||
|
||||
// TODO: Check to make sure that we're not clobering an existing file before opening.
|
||||
// Check to make sure that we're not clobering an existing file before opening.
|
||||
bool bFileNameChanging =
|
||||
pSteps->GetSavedToDisk() &&
|
||||
pSteps->GetFilename() != sPath;
|
||||
if( bFileNameChanging && DoesFileExist(sPath) )
|
||||
{
|
||||
sErrorOut = ssprintf( DESTINATION_ALREADY_EXISTS.GetValue(), sPath.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
RageFile f;
|
||||
if( !f.Open(sPath, RageFile::WRITE | RageFile::SLOW_FLUSH) )
|
||||
{
|
||||
LOG->Warn( "Error opening song file '%s' for writing: %s", sPath.c_str(), f.GetError().c_str() );
|
||||
sErrorOut = ssprintf( ERROR_WRITING_FILE.GetValue(), sPath.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -294,20 +305,20 @@ bool NotesWriterSM::WriteEditFileToMachine( const Song *pSong, Steps *pSteps )
|
||||
GetEditFileContents( pSong, pSteps, sTag );
|
||||
if( f.PutLine(sTag) == -1 || f.Flush() == -1 )
|
||||
{
|
||||
LOG->Warn( "Error writing song file '%s': %s", sPath.c_str(), f.GetError().c_str() );
|
||||
sErrorOut = ssprintf( ERROR_WRITING_FILE.GetValue(), sPath.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the file name of the edit has changed since the last save, then delete the old
|
||||
* file after saving the new one. If we delete it first, then we'll lose data on error. */
|
||||
bool bFileNameChanged =
|
||||
pSteps->GetSavedToDisk() &&
|
||||
pSteps->GetFilename() != sPath;
|
||||
|
||||
if( bFileNameChanged )
|
||||
if( bFileNameChanging )
|
||||
FILEMAN->Remove( pSteps->GetFilename() );
|
||||
pSteps->SetFilename( sPath );
|
||||
|
||||
/* Flush dir cache or else the new file won't be seen. */
|
||||
FILEMAN->FlushDirCache( Dirname(sPath) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
bool Write( RString sPath, const Song &out, bool bSavingCache );
|
||||
static void GetEditFileContents( const Song *pSong, const Steps *pSteps, RString &sOut );
|
||||
RString GetEditFileName( const Song *pSong, const Steps *pSteps );
|
||||
bool WriteEditFileToMachine( const Song *pSong, Steps *pSteps );
|
||||
bool WriteEditFileToMachine( const Song *pSong, Steps *pSteps, RString &sErrorOut );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2677,10 +2677,13 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector<int> &iAns
|
||||
{
|
||||
ASSERT( pSteps->IsAnEdit() );
|
||||
|
||||
// XXX show error
|
||||
NotesWriterSM w;
|
||||
if( !w.WriteEditFileToMachine(pSong, pSteps) )
|
||||
RString sError;
|
||||
if( !w.WriteEditFileToMachine(pSong,pSteps,sError) )
|
||||
{
|
||||
ScreenPrompt::Prompt( SM_None, sError );
|
||||
break;
|
||||
}
|
||||
|
||||
// HACK: clear undo, so "exit" below knows we don't need to save.
|
||||
// This only works because important non-steps data can't be changed in
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
#include "LocalizedString.h"
|
||||
#include "OptionRowHandler.h"
|
||||
#include "SongUtil.h"
|
||||
#include "song.h"
|
||||
#include "ProfileManager.h"
|
||||
#include "Profile.h"
|
||||
#include "SpecialFiles.h"
|
||||
#include "NotesWriterSM.h"
|
||||
|
||||
AutoScreenMessage( SM_BackFromRename )
|
||||
AutoScreenMessage( SM_BackFromDelete )
|
||||
@@ -49,6 +54,12 @@ void ScreenOptionsManageEditSteps::Init()
|
||||
|
||||
void ScreenOptionsManageEditSteps::BeginScreen()
|
||||
{
|
||||
// Reload so that we're consistent with the disk in case the user has been dinking around with their edits.
|
||||
SONGMAN->FreeAllLoadedFromProfile( ProfileSlot_Machine );
|
||||
SONGMAN->LoadAllFromProfileDir( PROFILEMAN->GetProfileDir(ProfileSlot_Machine), ProfileSlot_Machine );
|
||||
GAMESTATE->m_pCurSong.Set( NULL );
|
||||
GAMESTATE->m_pCurSteps[0].Set( NULL );
|
||||
|
||||
vector<OptionRowHandler*> vHands;
|
||||
|
||||
int iIndex = 0;
|
||||
@@ -71,7 +82,10 @@ void ScreenOptionsManageEditSteps::BeginScreen()
|
||||
{
|
||||
vHands.push_back( OptionRowHandlerUtil::MakeNull() );
|
||||
OptionRowDefinition &def = vHands.back()->m_Def;
|
||||
def.m_sName = (*s)->GetDescription();
|
||||
|
||||
Song *pSong = SONGMAN->GetSongFromSteps( *s );
|
||||
|
||||
def.m_sName = pSong->GetTranslitFullTitle() + " - " + (*s)->GetDescription();
|
||||
def.m_bAllowThemeTitle = false; // not themable
|
||||
def.m_sExplanationName = "Select Edit Steps";
|
||||
def.m_vsChoices.clear();
|
||||
@@ -132,8 +146,20 @@ void ScreenOptionsManageEditSteps::HandleScreenMessage( const ScreenMessage SM )
|
||||
if( !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this
|
||||
|
||||
GAMESTATE->m_pCurSteps[PLAYER_1]->SetDescription( ScreenTextEntry::s_sLastAnswer );
|
||||
|
||||
Steps *pSteps = GAMESTATE->m_pCurSteps[PLAYER_1];
|
||||
Song *pSong = SONGMAN->GetSongFromSteps( pSteps );
|
||||
|
||||
RString sOldDescription = pSteps->GetDescription();
|
||||
pSteps->SetDescription( ScreenTextEntry::s_sLastAnswer );
|
||||
|
||||
RString sError;
|
||||
NotesWriterSM sm;
|
||||
if( !sm.WriteEditFileToMachine(pSong,pSteps,sError) )
|
||||
{
|
||||
ScreenPrompt::Prompt( SM_None, sError );
|
||||
return;
|
||||
}
|
||||
|
||||
SCREENMAN->SetNewScreen( this->m_sName ); // reload
|
||||
}
|
||||
|
||||
@@ -425,10 +425,11 @@ RString SongUtil::MakeUniqueEditDescription( const Song *pSong, StepsType st, co
|
||||
|
||||
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." );
|
||||
|
||||
static LocalizedString EDIT_NAME_CANNOT_CONTAIN ( "SongUtil", "The edit name cannot contain any of the following characters: %s" );
|
||||
bool SongUtil::ValidateCurrentEditStepsDescription( const RString &sAnswer, RString &sErrorOut )
|
||||
{
|
||||
Steps *pSteps = GAMESTATE->m_pCurSteps[PLAYER_1];
|
||||
Song *pSong = SONGMAN->GetSongFromSteps( pSteps );
|
||||
|
||||
ASSERT( pSteps->IsAnEdit() );
|
||||
|
||||
@@ -438,9 +439,16 @@ bool SongUtil::ValidateCurrentEditStepsDescription( const RString &sAnswer, RStr
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps name must be unique
|
||||
static const RString sInvalidChars = "\\/:*?\"<>|";
|
||||
if( strpbrk(sAnswer, sInvalidChars) != NULL )
|
||||
{
|
||||
sErrorOut = ssprintf( EDIT_NAME_CANNOT_CONTAIN.GetValue(), sInvalidChars.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps name must be unique for this song.
|
||||
vector<Steps*> v;
|
||||
SONGMAN->GetStepsLoadedFromProfile( v, ProfileSlot_Machine );
|
||||
pSong->GetSteps( v, STEPS_TYPE_INVALID, DIFFICULTY_EDIT );
|
||||
FOREACH_CONST( Steps*, v, s )
|
||||
{
|
||||
if( pSteps == *s )
|
||||
|
||||
Reference in New Issue
Block a user