Created
February 5, 2024 22:55
-
-
Save jsm222/eb1414b651e81a8ea20b20df8bb46556 to your computer and use it in GitHub Desktop.
mscore use libxml2 directly in qt6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/importexport/musicxml/CMakeLists.txt b/src/importexport/musicxml/CMakeLists.txt | |
index f9882fb776..1e06776c65 100644 | |
--- a/src/importexport/musicxml/CMakeLists.txt | |
+++ b/src/importexport/musicxml/CMakeLists.txt | |
@@ -19,9 +19,11 @@ | |
# along with this program. If not, see <https://www.gnu.org/licenses/>. | |
set(MODULE iex_musicxml) | |
- | |
set(MODULE_QRC musicxml.qrc) | |
+find_package(LibXml2 REQUIRED) | |
+include_directories("${LIBXML2_INCLUDE_DIRS}") | |
+ | |
include(${CMAKE_CURRENT_LIST_DIR}/internal/musicxml/musicxml.cmake) | |
set(MODULE_SRC | |
@@ -41,6 +43,7 @@ set(MODULE_SRC | |
set(MODULE_LINK | |
engraving | |
+ "${LIBXML2_LIBRARIES}" | |
) | |
include(SetupModule) | |
diff --git a/src/importexport/musicxml/internal/musicxml/importxml.cpp b/src/importexport/musicxml/internal/musicxml/importxml.cpp | |
index dc41844a54..4e51c36832 100644 | |
--- a/src/importexport/musicxml/internal/musicxml/importxml.cpp | |
+++ b/src/importexport/musicxml/internal/musicxml/importxml.cpp | |
@@ -31,6 +31,8 @@ | |
//#include <QXmlSchemaValidator> | |
#include "importmxml.h" | |
+#include <libxml/xmlschemastypes.h> | |
+#include <libxml/catalog.h> | |
#include "musicxmlsupport.h" | |
#include "translation.h" | |
@@ -66,44 +68,6 @@ static_assert(int(DurationType::V_BREVE) == int(DurationType::V_LONG) + 1 | |
&& int(DurationType::V_512TH) == int(DurationType::V_256TH) + 1 | |
&& int(DurationType::V_1024TH) == int(DurationType::V_512TH) + 1); | |
-//--------------------------------------------------------- | |
-// initMusicXmlSchema | |
-// return false on error | |
-//--------------------------------------------------------- | |
- | |
-//static bool initMusicXmlSchema(QXmlSchema& schema) | |
-//{ | |
-// // read the MusicXML schema from the application resources | |
-// QFile schemaFile(":/schema/musicxml.xsd"); | |
-// if (!schemaFile.open(QIODevice::ReadOnly | QIODevice::Text)) { | |
-// LOGE("initMusicXmlSchema() could not open resource musicxml.xsd"); | |
-// return false; | |
-// } | |
- | |
-// // copy the schema into a QByteArray and fixup xs:imports, | |
-// // using a path to the application resources instead of to www.musicxml.org | |
-// // to prevent downloading from the net | |
-// QByteArray schemaBa; | |
-// QTextStream schemaStream(&schemaFile); | |
-// while (!schemaStream.atEnd()) { | |
-// QString line = schemaStream.readLine(); | |
-// if (line.contains("xs:import")) { | |
-// line.replace("http://www.musicxml.org/xsd", "qrc:///schema"); | |
-// } | |
-// schemaBa += line.toUtf8(); | |
-// schemaBa += "\n"; | |
-// } | |
- | |
-// // load and validate the schema | |
-// schema.load(schemaBa); | |
-// if (!schema.isValid()) { | |
-// LOGE("initMusicXmlSchema() internal error: MusicXML schema is invalid"); | |
-// return false; | |
-// } | |
- | |
-// return true; | |
-//} | |
- | |
//--------------------------------------------------------- | |
// musicXMLValidationErrorDialog | |
//--------------------------------------------------------- | |
@@ -114,18 +78,52 @@ static_assert(int(DurationType::V_BREVE) == int(DurationType::V_LONG) + 1 | |
Return QMessageBox::Yes (try anyway) or QMessageBox::No (don't) | |
*/ | |
-static int musicXMLValidationErrorDialog(QString text, QString detailedText) | |
+static int musicXMLValidationErrorDialog(void *ctxt,const char *fmt,...) | |
{ | |
+ std::string format(fmt); | |
+ std::string fstr("%s"); | |
+ int count=0; | |
+ int nPos = format.find(fstr, 0); // fist occurrence | |
+ | |
+ while (nPos != std::string::npos) | |
+ { | |
+ count++; | |
+ nPos = format.find(fstr, nPos + 1); | |
+ } | |
+ | |
QMessageBox errorDialog; | |
+ std::va_list argp; | |
+ va_start(argp, fmt); | |
+ std::string detailedError; | |
+ for(int i=0;i<count;i++) { | |
+ char * t = (char*)malloc(sizeof(char)*4096); | |
+ t = va_arg(argp, char*); | |
+ std::string str(t); | |
+ detailedError+=str; | |
+ free(t); | |
+ } | |
+ | |
+ va_end(argp); | |
errorDialog.setIcon(QMessageBox::Question); | |
- errorDialog.setText(text); | |
+ errorDialog.setText("Xml parser error"); | |
errorDialog.setInformativeText(qtrc("iex_musicxml", "Do you want to try to load this file anyway?")); | |
- errorDialog.setDetailedText(detailedText); | |
+ errorDialog.setDetailedText(QString::fromStdString(detailedError)); | |
errorDialog.setStandardButtons(QMessageBox::Yes | QMessageBox::No); | |
errorDialog.setDefaultButton(QMessageBox::No); | |
return errorDialog.exec(); | |
} | |
+//--------------------------------------------------------- | |
+// initMusicXmlSchema | |
+// return false on error | |
+//--------------------------------------------------------- | |
+static bool initMusicXmlSchema() | |
+{ | |
+ xmlSchemaParserCtxtPtr ctxt; | |
+ ctxt = xmlSchemaNewParserCtxt(QFile(":/schema/musicxml.xsd").fileName().toStdString().c_str()); | |
+ xmlSchemaSetParserErrors(ctxt, (xmlSchemaValidityErrorFunc) musicXMLValidationErrorDialog, (xmlSchemaValidityWarningFunc) musicXMLValidationErrorDialog, ctxt); | |
+ return (ctxt); | |
+} | |
//--------------------------------------------------------- | |
// extractRootfile | |
//--------------------------------------------------------- | |
@@ -191,35 +189,62 @@ static bool extractRootfile(QFile* qf, QByteArray& data) | |
static Err doValidate(const QString& name, QIODevice* dev) | |
{ | |
- NOT_IMPLEMENTED; | |
- | |
- //QElapsedTimer t; | |
- //t.start(); | |
- | |
- // initialize the schema | |
-// ValidatorMessageHandler messageHandler; | |
-// QXmlSchema schema; | |
-// schema.setMessageHandler(&messageHandler); | |
-// if (!initMusicXmlSchema(schema)) { | |
-// return Err::FileBadFormat; // appropriate error message has been printed by initMusicXmlSchema | |
-// } | |
-// // validate the data | |
-// QXmlSchemaValidator validator(schema); | |
-// bool valid = validator.validate(dev, QUrl::fromLocalFile(name)); | |
-// //LOGD("Validation time elapsed: %d ms", t.elapsed()); | |
- | |
-// if (!valid) { | |
-// LOGD("importMusicXml() file '%s' is not a valid MusicXML file", qPrintable(name)); | |
-// QString strErr = qtrc("iex_musicxml", "File “%1” is not a valid MusicXML file.").arg(name); | |
-// if (MScore::noGui) { | |
-// return Err::NoError; // might as well try anyhow in converter mode | |
-// } | |
-// if (musicXMLValidationErrorDialog(strErr, messageHandler.getErrors()) != QMessageBox::Yes) { | |
-// return Err::UserAbort; | |
-// } | |
-// } | |
- | |
- return Err::NoError; | |
+ xmlLoadCatalog("/home/jesper/Hentet/schema/catalog.xml"); | |
+ Err error = Err::UnknownError; | |
+ xmlDocPtr doc; | |
+ xmlSchemaPtr schema = NULL; | |
+ xmlSchemaParserCtxtPtr ctxt; | |
+ ctxt = xmlSchemaNewParserCtxt("/home/jesper/Hentet/schema/musicxml.xsd"); | |
+ xmlLineNumbersDefault(1); | |
+ | |
+ | |
+ xmlSchemaSetParserErrors(ctxt, (xmlSchemaValidityErrorFunc) musicXMLValidationErrorDialog, (xmlSchemaValidityWarningFunc) musicXMLValidationErrorDialog,ctxt); | |
+ schema = xmlSchemaParse(ctxt); | |
+ xmlSchemaFreeParserCtxt(ctxt); | |
+ | |
+ | |
+ doc = xmlReadFile(name.toStdString().c_str(), NULL, 0); | |
+ | |
+ if (doc == NULL) | |
+ { | |
+ std::cout << "Could not parse " << name.toStdString() << "\n"; | |
+ } | |
+ else | |
+ { | |
+ xmlSchemaValidCtxtPtr ctxt; | |
+ int ret; | |
+ | |
+ ctxt = xmlSchemaNewValidCtxt(schema); | |
+ xmlSchemaSetValidErrors(ctxt, (xmlSchemaValidityErrorFunc) musicXMLValidationErrorDialog, (xmlSchemaValidityWarningFunc) musicXMLValidationErrorDialog,ctxt); | |
+ ret = xmlSchemaValidateDoc(ctxt, doc); | |
+ if (ret == 0) | |
+ { | |
+ error = Err::NoError; | |
+ } | |
+ else if (ret > 0) | |
+ { | |
+ std::cout <<"fails to validate"<< name.toStdString() << "\n"; | |
+ error = Err::FileCorrupted; | |
+ } | |
+ else | |
+ { | |
+ std::cout <<"fails to validate internal error" << "\n"; | |
+ error = Err::UnknownError; | |
+ | |
+ } | |
+ xmlSchemaFreeValidCtxt(ctxt); | |
+ xmlFreeDoc(doc); | |
+ } | |
+ | |
+ | |
+ if(schema != NULL) | |
+ xmlSchemaFree(schema); | |
+ | |
+ xmlSchemaCleanupTypes(); | |
+ xmlCleanupParser(); | |
+ xmlMemoryDump(); | |
+ | |
+ return error; | |
} | |
//--------------------------------------------------------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment