Trying to load an invalid world editor file shouldn't crash the application, and an error messagebox should inform the user.
This commit is contained in:
parent
13cfad6336
commit
b72b78fb84
3 changed files with 66 additions and 38 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue