Trying to load an invalid world editor file shouldn't crash the application, and an error messagebox should inform the user.

--HG--
branch : gsoc2014-dfighter
This commit is contained in:
dfighter1985 2014-07-13 21:38:14 +02:00
parent 3517283526
commit 2d865a8567
3 changed files with 66 additions and 38 deletions

View file

@ -34,35 +34,11 @@ namespace WorldEditor
namespace Utils namespace Utils
{ {
void syntaxError(const char *filename, xmlNodePtr xmlNode, const char *format, ...) std::string lastError;
{
char buffer[1024];
if (format) std::string getLastError()
{ {
va_list args; return lastError;
va_start( args, format );
sint ret = vsnprintf( buffer, 1024, format, args );
va_end( args );
}
else
{
strcpy(buffer, "Unknown error");
}
nlerror("(%s), node (%s), line (%s) :\n%s", filename, xmlNode->name, xmlNode->content, buffer);
}
bool getPropertyString(std::string &result, const char *filename, xmlNodePtr xmlNode, const char *propName)
{
// Call the CIXml version
if (!NLMISC::CIXml::getPropertyString(result, xmlNode, propName))
{
// Output a formated error
syntaxError(filename, xmlNode, "Missing XML node property (%s)", propName);
return false;
}
return true;
} }
uint32 getUniqueId() uint32 getUniqueId()
@ -81,6 +57,8 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList
{ {
bool result = false; bool result = false;
lastError = "";
// Load the document // Load the document
NLMISC::CIFile file; NLMISC::CIFile file;
if (file.open(fileName)) if (file.open(fileName))
@ -110,20 +88,31 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList
} }
if (version == -1) if (version == -1)
syntaxError(fileName.c_str(), rootNode, "No version node"); {
std::string error = "No version node in file " + fileName;
lastError = error;
nlinfo( "%s", error.c_str() );
return false;
}
else else
{ {
// Old format, // Old format,
if (version <= 1) if (version <= 1)
{ {
syntaxError(fileName.c_str(), rootNode, "Old version node"); std::string error = "Old version node in file " + fileName;
lastError = error;
nlinfo( "%s", error.c_str() );
return false;
} }
else else
{ {
// Read it // Read it
if (version > WORLD_EDITOR_FILE_VERSION) if (version > WORLD_EDITOR_FILE_VERSION)
{ {
syntaxError(fileName.c_str(), node, "Unknown file version"); std::string error = "Unknown file version in file " + fileName;
lastError = error;
nlinfo( "%s", error.c_str() );
return false;
} }
else else
{ {
@ -153,11 +142,12 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList
{ {
// Get the type // Get the type
std::string type; std::string type;
if (getPropertyString(type, fileName.c_str(), node, "TYPE"))
if ( NLMISC::CIXml::getPropertyString(type, node, "TYPE"))
{ {
// Read the filename // Read the filename
std::string filenameChild; std::string filenameChild;
if (getPropertyString(filenameChild, fileName.c_str(), node, "FILENAME")) if ( NLMISC::CIXml::getPropertyString(filenameChild, node, "FILENAME"))
{ {
// Is it a landscape ? // Is it a landscape ?
if (type == "landscape") if (type == "landscape")
@ -179,11 +169,34 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList
} }
} }
else else
if ( type == "primitive" )
{ {
worldEditList.push_back(WorldEditItem(PrimitiveType, filenameChild)); worldEditList.push_back(WorldEditItem(PrimitiveType, filenameChild));
} }
else
if( type.empty() )
{
std::string error = "Empty type node property in file " + fileName;
lastError = error;
nlinfo( "%s", error.c_str() );
return false;
}
} }
else
{
std::string error = "Missing filename node property in file " + fileName;
lastError = error;
nlinfo( "%s", error.c_str() );
return false;
}
}
else
{
std::string error = "Missing type node property in file " + fileName;
lastError = error;
nlinfo( "%s", error.c_str() );
return false;
} }
} }
while (node = NLMISC::CIXml::getNextChildNode(node, "DATABASE_ELEMENT")); while (node = NLMISC::CIXml::getNextChildNode(node, "DATABASE_ELEMENT"));
@ -197,18 +210,26 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList
} }
else else
{ {
// Error std::string error = "Unknown file header in file " + fileName;
syntaxError(fileName.c_str(), rootNode, "Unknown file header : %s", rootNode->name); lastError = error;
nlinfo( "%s", error.c_str() );
return false;
} }
} }
} }
catch (NLMISC::Exception &e) catch (NLMISC::Exception &e)
{ {
nlerror("Error reading file %s : %s", fileName.c_str(), e.what()); std::string error = "Error reading file " + fileName + " : " + std::string( e.what() );
lastError = error;
nlinfo( "%s", error.c_str() );
} }
} }
else else
nlerror("Can't open the file %s for reading.", fileName.c_str()); {
std::string error = "Can't open the file " + fileName + " for reading.";
lastError = error;
nlinfo( "%s", error.c_str() );
}
return result; return result;
} }

View file

@ -49,6 +49,8 @@ typedef std::vector<WorldEditItem> WorldEditList;
// Generate unique identificator // Generate unique identificator
uint32 getUniqueId(); uint32 getUniqueId();
std::string getLastError();
// Load *.worldedit file and return list primitives and landscapes. // Load *.worldedit file and return list primitives and landscapes.
bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList); bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList);

View file

@ -174,7 +174,12 @@ void WorldEditorWindow::loadWorldEditFile(const QString &fileName)
Utils::WorldEditList worldEditList; Utils::WorldEditList worldEditList;
if (!Utils::loadWorldEditFile(fileName.toUtf8().constData(), worldEditList)) if (!Utils::loadWorldEditFile(fileName.toUtf8().constData(), worldEditList))
{ {
// TODO: add the message box std::string error = Utils::getLastError();
QMessageBox::critical( this,
tr( "Error opening world editor file" ),
tr( error.c_str() ) );
return; return;
} }