mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-18 09:00:07 +02:00
Use TranslatableString in XMLFileReader & move the help URL logic
This commit is contained in:
parent
503ccabdd8
commit
89df7a3ffc
@ -85,6 +85,55 @@ ProjectFileManager::ProjectFileManager( AudacityProject &project )
|
|||||||
|
|
||||||
ProjectFileManager::~ProjectFileManager() = default;
|
ProjectFileManager::~ProjectFileManager() = default;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char *const defaultHelpUrl =
|
||||||
|
"FAQ:Errors_on_opening_or_recovering_an_Audacity_project";
|
||||||
|
|
||||||
|
using Pair = std::pair< const char *, const char * >;
|
||||||
|
const Pair helpURLTable[] = {
|
||||||
|
{
|
||||||
|
"not well-formed (invalid token)",
|
||||||
|
"Error:_not_well-formed_(invalid_token)_at_line_x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reference to invalid character number",
|
||||||
|
"Error_Opening_Project:_Reference_to_invalid_character_number_at_line_x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mismatched tag",
|
||||||
|
"#mismatched"
|
||||||
|
},
|
||||||
|
// These two errors with FAQ entries are reported elsewhere, not here....
|
||||||
|
//#[[#import-error|Error Importing: Aup is an Audacity Project file. Use the File > Open command]]
|
||||||
|
//#[[#corrupt|Error Opening File or Project: File may be invalid or corrupted]]
|
||||||
|
};
|
||||||
|
|
||||||
|
wxString FindHelpUrl( const TranslatableString &libraryError )
|
||||||
|
{
|
||||||
|
wxString helpUrl;
|
||||||
|
if ( !libraryError.empty() ) {
|
||||||
|
helpUrl = defaultHelpUrl;
|
||||||
|
|
||||||
|
auto msgid = libraryError.MSGID().GET();
|
||||||
|
auto found = std::find_if( begin(helpURLTable), end(helpURLTable),
|
||||||
|
[&]( const Pair &pair ) {
|
||||||
|
return msgid.Contains( pair.first ); }
|
||||||
|
);
|
||||||
|
if (found != end(helpURLTable)) {
|
||||||
|
auto url = found->second;
|
||||||
|
if (url[0] == '#')
|
||||||
|
helpUrl += url;
|
||||||
|
else
|
||||||
|
helpUrl = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return helpUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
auto ProjectFileManager::ReadProjectFile( const FilePath &fileName )
|
auto ProjectFileManager::ReadProjectFile( const FilePath &fileName )
|
||||||
-> ReadProjectResults
|
-> ReadProjectResults
|
||||||
{
|
{
|
||||||
@ -172,7 +221,10 @@ auto ProjectFileManager::ReadProjectFile( const FilePath &fileName )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { false, bParseSuccess, err, xmlFile.GetErrorStr() };
|
return {
|
||||||
|
false, bParseSuccess, err, xmlFile.GetErrorStr(),
|
||||||
|
FindHelpUrl( xmlFile.GetLibraryErrorStr() )
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
///gets an int with OD flags so that we can determine which ODTasks should be run on this track after save/open, etc.
|
///gets an int with OD flags so that we can determine which ODTasks should be run on this track after save/open, etc.
|
||||||
@ -1337,7 +1389,7 @@ void ProjectFileManager::OpenFile(const FilePath &fileNameArg, bool addtohistory
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const bool bParseSuccess = results.parseSuccess;
|
const bool bParseSuccess = results.parseSuccess;
|
||||||
const wxString &errorStr = results.errorString;
|
const auto &errorStr = results.errorString;
|
||||||
const bool err = results.trackError;
|
const bool err = results.trackError;
|
||||||
|
|
||||||
if (bParseSuccess) {
|
if (bParseSuccess) {
|
||||||
@ -1476,73 +1528,13 @@ void ProjectFileManager::OpenFile(const FilePath &fileNameArg, bool addtohistory
|
|||||||
project.SetFileName( wxT("") );
|
project.SetFileName( wxT("") );
|
||||||
projectFileIO.SetProjectTitle();
|
projectFileIO.SetProjectTitle();
|
||||||
|
|
||||||
wxLogError(wxT("Could not parse file \"%s\". \nError: %s"), fileName, errorStr);
|
wxLogError(wxT("Could not parse file \"%s\". \nError: %s"), fileName, errorStr.Debug());
|
||||||
|
|
||||||
wxString url = wxT("FAQ:Errors_on_opening_or_recovering_an_Audacity_project");
|
|
||||||
|
|
||||||
// Certain errors have dedicated help.
|
|
||||||
// On April-4th-2018, we did not request translation of the XML errors.
|
|
||||||
// If/when we do, we will need _() around the comparison strings.
|
|
||||||
if( errorStr.Contains( ("not well-formed (invalid token)") ) )
|
|
||||||
url = "Error:_not_well-formed_(invalid_token)_at_line_x";
|
|
||||||
else if( errorStr.Contains(("reference to invalid character number") ))
|
|
||||||
url = "Error_Opening_Project:_Reference_to_invalid_character_number_at_line_x";
|
|
||||||
else if( errorStr.Contains(("mismatched tag") ))
|
|
||||||
url += "#mismatched";
|
|
||||||
|
|
||||||
// These two errors with FAQ entries are reported elsewhere, not here....
|
|
||||||
//#[[#import-error|Error Importing: Aup is an Audacity Project file. Use the File > Open command]]
|
|
||||||
//#[[#corrupt|Error Opening File or Project: File may be invalid or corrupted]]
|
|
||||||
|
|
||||||
// If we did want to handle every single parse error, these are they....
|
|
||||||
/*
|
|
||||||
XML_L("out of memory"),
|
|
||||||
XML_L("syntax error"),
|
|
||||||
XML_L("no element found"),
|
|
||||||
XML_L("not well-formed (invalid token)"),
|
|
||||||
XML_L("unclosed token"),
|
|
||||||
XML_L("partial character"),
|
|
||||||
XML_L("mismatched tag"),
|
|
||||||
XML_L("duplicate attribute"),
|
|
||||||
XML_L("junk after document element"),
|
|
||||||
XML_L("illegal parameter entity reference"),
|
|
||||||
XML_L("undefined entity"),
|
|
||||||
XML_L("recursive entity reference"),
|
|
||||||
XML_L("asynchronous entity"),
|
|
||||||
XML_L("reference to invalid character number"),
|
|
||||||
XML_L("reference to binary entity"),
|
|
||||||
XML_L("reference to external entity in attribute"),
|
|
||||||
XML_L("XML or text declaration not at start of entity"),
|
|
||||||
XML_L("unknown encoding"),
|
|
||||||
XML_L("encoding specified in XML declaration is incorrect"),
|
|
||||||
XML_L("unclosed CDATA section"),
|
|
||||||
XML_L("error in processing external entity reference"),
|
|
||||||
XML_L("document is not standalone"),
|
|
||||||
XML_L("unexpected parser state - please send a bug report"),
|
|
||||||
XML_L("entity declared in parameter entity"),
|
|
||||||
XML_L("requested feature requires XML_DTD support in Expat"),
|
|
||||||
XML_L("cannot change setting once parsing has begun"),
|
|
||||||
XML_L("unbound prefix"),
|
|
||||||
XML_L("must not undeclare prefix"),
|
|
||||||
XML_L("incomplete markup in parameter entity"),
|
|
||||||
XML_L("XML declaration not well-formed"),
|
|
||||||
XML_L("text declaration not well-formed"),
|
|
||||||
XML_L("illegal character(s) in public id"),
|
|
||||||
XML_L("parser suspended"),
|
|
||||||
XML_L("parser not suspended"),
|
|
||||||
XML_L("parsing aborted"),
|
|
||||||
XML_L("parsing finished"),
|
|
||||||
XML_L("cannot suspend in external parameter entity"),
|
|
||||||
XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
|
|
||||||
XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
|
|
||||||
XML_L("prefix must not be bound to one of the reserved namespace names")
|
|
||||||
*/
|
|
||||||
|
|
||||||
ShowErrorDialog(
|
ShowErrorDialog(
|
||||||
&window,
|
&window,
|
||||||
XO("Error Opening Project"),
|
XO("Error Opening Project"),
|
||||||
errorStr,
|
errorStr.Translation(),
|
||||||
url);
|
results.helpUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ public:
|
|||||||
bool decodeError;
|
bool decodeError;
|
||||||
bool parseSuccess;
|
bool parseSuccess;
|
||||||
bool trackError;
|
bool trackError;
|
||||||
wxString errorString;
|
TranslatableString errorString;
|
||||||
|
wxString helpUrl;
|
||||||
};
|
};
|
||||||
ReadProjectResults ReadProjectFile( const FilePath &fileName );
|
ReadProjectResults ReadProjectFile( const FilePath &fileName );
|
||||||
|
|
||||||
|
@ -1268,7 +1268,7 @@ void TagsEditorDialog::OnLoad(wxCommandEvent & WXUNUSED(event))
|
|||||||
XMLFileReader reader;
|
XMLFileReader reader;
|
||||||
if (!reader.Parse(&mLocal, fn)) {
|
if (!reader.Parse(&mLocal, fn)) {
|
||||||
// Inform user of load failure
|
// Inform user of load failure
|
||||||
AudacityMessageBox(reader.GetErrorStr(),
|
AudacityMessageBox(reader.GetErrorStr().Translation(),
|
||||||
_("Error Loading Metadata"),
|
_("Error Loading Metadata"),
|
||||||
wxOK | wxCENTRE,
|
wxOK | wxCENTRE,
|
||||||
this);
|
this);
|
||||||
|
@ -3437,7 +3437,7 @@ bool VSTEffect::LoadXML(const wxFileName & fn)
|
|||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
// Inform user of load failure
|
// Inform user of load failure
|
||||||
AudacityMessageBox(reader.GetErrorStr(),
|
AudacityMessageBox(reader.GetErrorStr().Translation(),
|
||||||
_("Error Loading VST Presets"),
|
_("Error Loading VST Presets"),
|
||||||
wxOK | wxCENTRE,
|
wxOK | wxCENTRE,
|
||||||
mParent);
|
mParent);
|
||||||
|
@ -358,7 +358,7 @@ void KeyConfigPrefs::OnImport(wxCommandEvent & WXUNUSED(event))
|
|||||||
|
|
||||||
XMLFileReader reader;
|
XMLFileReader reader;
|
||||||
if (!reader.Parse(mManager, file)) {
|
if (!reader.Parse(mManager, file)) {
|
||||||
AudacityMessageBox(reader.GetErrorStr(),
|
AudacityMessageBox(reader.GetErrorStr().Translation(),
|
||||||
_("Error Importing Keyboard Shortcuts"),
|
_("Error Importing Keyboard Shortcuts"),
|
||||||
wxOK | wxCENTRE, this);
|
wxOK | wxCENTRE, this);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ bool XMLFileReader::Parse(XMLTagHandler *baseHandler,
|
|||||||
{
|
{
|
||||||
wxFFile theXMLFile(fname, wxT("rb"));
|
wxFFile theXMLFile(fname, wxT("rb"));
|
||||||
if (!theXMLFile.IsOpened()) {
|
if (!theXMLFile.IsOpened()) {
|
||||||
mErrorStr.Printf(_("Could not open file: \"%s\""), fname);
|
mErrorStr = XO("Could not open file: \"%s\"").Format( fname );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,11 +54,66 @@ bool XMLFileReader::Parse(XMLTagHandler *baseHandler,
|
|||||||
size_t len = fread(buffer, 1, bufferSize, theXMLFile.fp());
|
size_t len = fread(buffer, 1, bufferSize, theXMLFile.fp());
|
||||||
done = (len < bufferSize);
|
done = (len < bufferSize);
|
||||||
if (!XML_Parse(mParser, buffer, len, done)) {
|
if (!XML_Parse(mParser, buffer, len, done)) {
|
||||||
mErrorStr.Printf(_("Error: %hs at line %lu"),
|
|
||||||
XML_ErrorString(XML_GetErrorCode(mParser)),
|
// Embedded error string from expat doesn't translate (yet)
|
||||||
(long unsigned int)XML_GetCurrentLineNumber(mParser));
|
// We could make a table of XOs if we wanted so that it could
|
||||||
|
// If we do, uncomment the second constructor argument so it's not
|
||||||
|
// a verbatim string
|
||||||
|
mLibraryErrorStr = TranslatableString{
|
||||||
|
XML_ErrorString(XML_GetErrorCode(mParser)) // , {}
|
||||||
|
};
|
||||||
|
|
||||||
|
mErrorStr = XO("Error: %s at line %lu").Format(
|
||||||
|
mLibraryErrorStr,
|
||||||
|
(long unsigned int)XML_GetCurrentLineNumber(mParser)
|
||||||
|
);
|
||||||
|
|
||||||
theXMLFile.Close();
|
theXMLFile.Close();
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// If we did want to handle every single parse error, these are they....
|
||||||
|
/*
|
||||||
|
XML_L("out of memory"),
|
||||||
|
XML_L("syntax error"),
|
||||||
|
XML_L("no element found"),
|
||||||
|
XML_L("not well-formed (invalid token)"),
|
||||||
|
XML_L("unclosed token"),
|
||||||
|
XML_L("partial character"),
|
||||||
|
XML_L("mismatched tag"),
|
||||||
|
XML_L("duplicate attribute"),
|
||||||
|
XML_L("junk after document element"),
|
||||||
|
XML_L("illegal parameter entity reference"),
|
||||||
|
XML_L("undefined entity"),
|
||||||
|
XML_L("recursive entity reference"),
|
||||||
|
XML_L("asynchronous entity"),
|
||||||
|
XML_L("reference to invalid character number"),
|
||||||
|
XML_L("reference to binary entity"),
|
||||||
|
XML_L("reference to external entity in attribute"),
|
||||||
|
XML_L("XML or text declaration not at start of entity"),
|
||||||
|
XML_L("unknown encoding"),
|
||||||
|
XML_L("encoding specified in XML declaration is incorrect"),
|
||||||
|
XML_L("unclosed CDATA section"),
|
||||||
|
XML_L("error in processing external entity reference"),
|
||||||
|
XML_L("document is not standalone"),
|
||||||
|
XML_L("unexpected parser state - please send a bug report"),
|
||||||
|
XML_L("entity declared in parameter entity"),
|
||||||
|
XML_L("requested feature requires XML_DTD support in Expat"),
|
||||||
|
XML_L("cannot change setting once parsing has begun"),
|
||||||
|
XML_L("unbound prefix"),
|
||||||
|
XML_L("must not undeclare prefix"),
|
||||||
|
XML_L("incomplete markup in parameter entity"),
|
||||||
|
XML_L("XML declaration not well-formed"),
|
||||||
|
XML_L("text declaration not well-formed"),
|
||||||
|
XML_L("illegal character(s) in public id"),
|
||||||
|
XML_L("parser suspended"),
|
||||||
|
XML_L("parser not suspended"),
|
||||||
|
XML_L("parsing aborted"),
|
||||||
|
XML_L("parsing finished"),
|
||||||
|
XML_L("cannot suspend in external parameter entity"),
|
||||||
|
XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
|
||||||
|
XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
|
||||||
|
XML_L("prefix must not be bound to one of the reserved namespace names")
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
} while (!done);
|
} while (!done);
|
||||||
|
|
||||||
@ -70,16 +125,21 @@ bool XMLFileReader::Parse(XMLTagHandler *baseHandler,
|
|||||||
if (mBaseHandler)
|
if (mBaseHandler)
|
||||||
return true;
|
return true;
|
||||||
else {
|
else {
|
||||||
mErrorStr.Printf(_("Could not load file: \"%s\""), fname);
|
mErrorStr = XO("Could not load file: \"%s\"").Format( fname );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString XMLFileReader::GetErrorStr()
|
const TranslatableString &XMLFileReader::GetErrorStr() const
|
||||||
{
|
{
|
||||||
return mErrorStr;
|
return mErrorStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TranslatableString &XMLFileReader::GetLibraryErrorStr() const
|
||||||
|
{
|
||||||
|
return mLibraryErrorStr;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void XMLFileReader::startElement(void *userData, const char *name,
|
void XMLFileReader::startElement(void *userData, const char *name,
|
||||||
const char **atts)
|
const char **atts)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "expat.h"
|
#include "expat.h"
|
||||||
|
|
||||||
#include "XMLTagHandler.h"
|
#include "XMLTagHandler.h"
|
||||||
#include "audacity/Types.h"
|
#include "Internat.h" // for TranslatableString
|
||||||
|
|
||||||
class AUDACITY_DLL_API XMLFileReader final {
|
class AUDACITY_DLL_API XMLFileReader final {
|
||||||
public:
|
public:
|
||||||
@ -24,7 +24,8 @@ class AUDACITY_DLL_API XMLFileReader final {
|
|||||||
bool Parse(XMLTagHandler *baseHandler,
|
bool Parse(XMLTagHandler *baseHandler,
|
||||||
const FilePath &fname);
|
const FilePath &fname);
|
||||||
|
|
||||||
wxString GetErrorStr();
|
const TranslatableString &GetErrorStr() const;
|
||||||
|
const TranslatableString &GetLibraryErrorStr() const;
|
||||||
|
|
||||||
// Callback functions for expat
|
// Callback functions for expat
|
||||||
|
|
||||||
@ -40,5 +41,6 @@ class AUDACITY_DLL_API XMLFileReader final {
|
|||||||
XMLTagHandler *mBaseHandler;
|
XMLTagHandler *mBaseHandler;
|
||||||
using Handlers = std::vector<XMLTagHandler*>;
|
using Handlers = std::vector<XMLTagHandler*>;
|
||||||
Handlers mHandler;
|
Handlers mHandler;
|
||||||
wxString mErrorStr;
|
TranslatableString mErrorStr;
|
||||||
|
TranslatableString mLibraryErrorStr;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user