diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index 3e9b906..41d0015 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -116,10 +116,23 @@ Button { anchors.verticalCenter: parent.verticalCenter visible: !hidden font.pixelSize: 14 - text: historyAction.getHTMLString().replace(/\$\{tag_color\}/g, clr) + text: "" textFormat: Text.RichText clip: true wrapMode: Text.WordWrap + + Component.onCompleted: function() { + // Render HTML, might be string, but could also be a promise + const html = historyAction.getHTMLString() + if(typeof html === "string") { + label.text = html.replace(/\$\{tag_color\}/g, clr) + } else { + // Promise! We need to way to wait for it to be completed. + html.then(rendered => { + label.text = rendered.replace(/\$\{tag_color\}/g, clr) + }) + } + } } Rectangle { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 3df3a77..db2d5dc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -109,24 +109,28 @@ export class Action { * Renders a LaTeX-formatted string to an image and wraps it in an HTML tag in a string. * * @param {string} latexString - Source string of the latex. - * @returns {string} + * @returns {Promise} */ renderLatexAsHtml(latexString) { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") - let imgDepth = Modules.History.imageDepth - let { source, width, height } = Latex.renderSync( - latexString, - imgDepth * (Modules.History.fontSize + 2), - Modules.History.themeTextColor - ) - return `` + return new Promise(resolve => { + let imgDepth = Modules.History.imageDepth + Latex.requestAsyncRender( + latexString, + imgDepth * (Modules.History.fontSize + 2), + Modules.History.themeTextColor + ).then((imgData) => { + const { source, width, height } = imgData + resolve(``) + }) + }) } /** * Returns a string with the HTML-formatted description of the action. * - * @returns {string} + * @returns {string|Promise} */ getHTMLString() { return this.getReadableString() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index 3540cfe..3c6bcda 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -85,8 +85,9 @@ export default class EditedProperty extends Action { } setReadableValues() { - this.prevString = ""; - this.nextString = ""; + this.prevString = "" + this.nextString = "" + this._renderPromises = [] if(this.propertyType instanceof Object) { switch(this.propertyType.type) { case "Enum": @@ -118,8 +119,11 @@ export default class EditedProperty extends Action { this.prevHTML = ' '+this.prevString+' ' this.nextHTML = ' '+this.nextString+' ' if(Latex.enabled && typeof this.propertyType == 'object' && this.propertyType.type === "Expression") { - this.prevHTML= this.renderLatexAsHtml(this.previousValue.latexMarkup) - this.nextHTML= this.renderLatexAsHtml(this.newValue.latexMarkup) + // Store promises so that querying can wait for them to finish. + this._renderPromises = [ + this.renderLatexAsHtml(this.previousValue.latexMarkup).then(prev => this.prevHTML = prev), + this.renderLatexAsHtml(this.newValue.latexMarkup).then(next => this.nextHTML = prev) + ] } } @@ -131,10 +135,21 @@ export default class EditedProperty extends Action { } getHTMLString() { - return qsTr('%1 of %2 changed from %3 to %4.') - .arg(this.targetPropertyReadable) - .arg(' ' + this.targetName + ' ') - .arg(this.prevHTML) - .arg(this.nextHTML) + return new Promise(resolve => { + const translation = qsTr('%1 of %2 changed from %3 to %4.') + .arg(this.targetPropertyReadable) + .arg(' ' + this.targetName + ' ') + // Check if we need to wait for LaTeX HTML to be rendered. + if(this.prevHTML !== undefined && this.nextHTML !== undefined) + resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) + else + Promise.all(this._renderPromises).then((rendered) => { + // Rendered are (potentially) two HTML strings which are defined during rendering + this.prevHTML = this.prevHTML ?? rendered[0] + this.nextHTML = this.prevHTML ?? rendered[1] + resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) + }) + }) + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index eaf4b65..15c3583 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -61,10 +61,15 @@ export default class EditedPosition extends Action { setReadableValues() { this.prevString = `(${this.previousXValue.toString()},${this.previousYValue.toString()})` this.nextString = `(${this.newXValue.toString()},${this.newYValue.toString()})` + this._renderPromises = [] // Render as LaTeX if(Latex.enabled) { - this.prevHTML = this.renderLatexAsHtml(`\\left(${this.previousXValue.latexMarkup},${this.previousYValue.latexMarkup}\\right)`) - this.nextHTML = this.renderLatexAsHtml(`\\left(${this.newXValue.latexMarkup},${this.newYValue.latexMarkup}\\right)`) + const prevMarkup = `\\left(${this.previousXValue.latexMarkup},${this.previousYValue.latexMarkup}\\right)` + const nextMarkup = `\\left(${this.newXValue.latexMarkup},${this.newYValue.latexMarkup}\\right)` + this._renderPromises = [ // Will be taken in promise.all + this.renderLatexAsHtml(prevMarkup), + this.renderLatexAsHtml(nextMarkup) + ] } else { this.prevHTML = ' '+escapeHTML(this.prevString)+' ' this.nextHTML = ' '+escapeHTML(this.nextString)+' ' @@ -85,9 +90,20 @@ export default class EditedPosition extends Action { } getHTMLString() { - return qsTr('Position of %1 set from %2 to %3.') - .arg(' ' + this.targetName + ' ') - .arg(this.prevHTML) - .arg(this.nextHTML) + return new Promise(resolve => { + const translation = qsTr('Position of %1 set from %2 to %3.') + .arg(' ' + this.targetName + ' ') + // Check if we need to wait for LaTeX HTML to be rendered. + if(this.prevHTML !== undefined && this.nextHTML !== undefined) + resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) + else + Promise.all(this._renderPromises).then((rendered) => { + // Rendered are (potentially) two HTML strings which are defined during rendering + this.prevHTML = this.prevHTML ?? rendered[0] + this.nextHTML = this.prevHTML ?? rendered[1] + resolve(translation.arg(this.prevHTML).arg(this.nextHTML)) + }) + }) + } }