From 917fb69990d3fc0241b11b0ed66fe3e4f6afba95 Mon Sep 17 00:00:00 2001 From: "mathias.chouet" <mathias.chouet@irstea.fr> Date: Wed, 16 Oct 2019 16:04:36 +0200 Subject: [PATCH] Solveur GUI interface for Solveur module draw Solveur relations in modules diagram view --- .../calculators/solveur/solveur.config.json | 6 +- src/app/calculators/solveur/solveur.en.json | 1 + src/app/calculators/solveur/solveur.fr.json | 1 + .../calculator.component.ts | 7 ++ .../modules-diagram.component.ts | 20 +++- .../select-field-line.component.ts | 12 ++- .../definition/concrete/form-solveur.ts | 76 +++++++++++---- .../formulaire/definition/form-definition.ts | 6 ++ src/app/formulaire/fieldset.ts | 37 +++++++- src/app/formulaire/ngparam.ts | 5 +- src/app/formulaire/select-field-nub.ts | 37 ++++++++ src/app/formulaire/select-field-parameter.ts | 36 ++++++++ src/app/formulaire/select-field-reference.ts | 92 +++++++++++++++++++ src/app/formulaire/select-field.ts | 24 +---- src/app/util.ts | 11 +++ src/locale/messages.en.json | 11 ++- src/locale/messages.fr.json | 11 ++- 17 files changed, 336 insertions(+), 57 deletions(-) create mode 100644 src/app/formulaire/select-field-nub.ts create mode 100644 src/app/formulaire/select-field-parameter.ts create mode 100644 src/app/formulaire/select-field-reference.ts diff --git a/src/app/calculators/solveur/solveur.config.json b/src/app/calculators/solveur/solveur.config.json index 7e6ac3bbd..40b0bbb8c 100644 --- a/src/app/calculators/solveur/solveur.config.json +++ b/src/app/calculators/solveur/solveur.config.json @@ -5,7 +5,8 @@ "fields": [ { "id": "select_target_nub", - "type": "select", + "type": "select_reference", + "reference": "nub", "source": "solveur_target" }, "Ytarget" @@ -17,7 +18,8 @@ "fields": [ { "id": "select_searched_param", - "type": "select", + "type": "select_reference", + "reference": "parameter", "source": "solveur_searched" }, "Xinit" diff --git a/src/app/calculators/solveur/solveur.en.json b/src/app/calculators/solveur/solveur.en.json index cbf67bcf2..df14b3764 100644 --- a/src/app/calculators/solveur/solveur.en.json +++ b/src/app/calculators/solveur/solveur.en.json @@ -4,6 +4,7 @@ "Ytarget": "Value of target parameter", "Xinit": "Initial value for searched parameter", + "X": "Value for searched parameter", "select_target_nub": "Module and parameter to calculate", "select_searched_param": "Searched parameter" diff --git a/src/app/calculators/solveur/solveur.fr.json b/src/app/calculators/solveur/solveur.fr.json index 86899fc0d..1439bd8da 100644 --- a/src/app/calculators/solveur/solveur.fr.json +++ b/src/app/calculators/solveur/solveur.fr.json @@ -4,6 +4,7 @@ "Ytarget": "Valeur du paramètre cible", "Xinit": "Valeur initiale du paramètre recherché", + "X": "Valeur du paramètre recherché", "select_target_nub": "Module et paramètre à calculer", "select_searched_param": "Paramètre recherché" diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index 82dc8d735..365fa61e7 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -376,6 +376,8 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe this._calculatorNameComponent.model = this._formulaire; // reload localisation in all cases this.formulaireService.loadUpdateFormulaireLocalisation(this._formulaire); + // call Form init hook + this._formulaire.onCalculatorInit(); break; } } else if (sender instanceof FormulaireDefinition) { @@ -530,6 +532,11 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe return (this.isPAB || this.isMRC); } + // true if current Nub is Solveur + public get isSolveur() { + return this.is(CalculatorType.Solveur); + } + // true if current Nub is PAB public get isPAB() { return this.is(CalculatorType.Pab); diff --git a/src/app/components/modules-diagram/modules-diagram.component.ts b/src/app/components/modules-diagram/modules-diagram.component.ts index 68297ad6c..d84bfdac7 100644 --- a/src/app/components/modules-diagram/modules-diagram.component.ts +++ b/src/app/components/modules-diagram/modules-diagram.component.ts @@ -16,7 +16,8 @@ import { LoiDebit, Nub, MacrorugoCompound, - Pab + Pab, + Solveur } from "jalhyd"; import { I18nService } from "../../services/internationalisation.service"; @@ -43,7 +44,7 @@ export class ModulesDiagramComponent implements AfterContentInit, AfterViewCheck private nativeElement: any; @ViewChild("diagram", { static: true }) - public diagram; + public diagram: any; public error: boolean; @@ -179,7 +180,7 @@ export class ModulesDiagramComponent implements AfterContentInit, AfterViewCheck // simple Nub (no children) def.push(f.uid + "(\"" + f.calculatorName + "\")"); } - // fnid all linked parameters + // find all linked parameters for (const p of nub.parameterIterator) { if (p.valueMode === ParamValueMode.LINK && p.isReferenceDefined()) { const target = p.referencedValue.nub; @@ -190,6 +191,19 @@ export class ModulesDiagramComponent implements AfterContentInit, AfterViewCheck def.push(nub.uid + "-->|" + symb + "|" + target.uid); } } + // add Solveur links + if (nub instanceof Solveur) { + const ntc = nub.nubToCalculate; + const sp = nub.searchedParameter; + const reads = this.intlService.localizeText("INFO_DIAGRAM_SOLVEUR_READS"); + const finds = this.intlService.localizeText("INFO_DIAGRAM_SOLVEUR_FINDS"); + if (ntc !== undefined) { + def.push(nub.uid + "-->|" + reads + ":" + ntc.calculatedParam.symbol + "|" + ntc.uid); + } + if (sp !== undefined) { + def.push(sp.nubUid + "-->|" + finds + ":" + sp.symbol + "|" + nub.uid); + } + } } return def.join("\n"); diff --git a/src/app/components/select-field-line/select-field-line.component.ts b/src/app/components/select-field-line/select-field-line.component.ts index 04a69146b..e9615dbed 100644 --- a/src/app/components/select-field-line/select-field-line.component.ts +++ b/src/app/components/select-field-line/select-field-line.component.ts @@ -1,8 +1,9 @@ -import { Component, Input } from "@angular/core"; +import { Component, Input, OnInit } from "@angular/core"; import { SelectField } from "../../formulaire/select-field"; import { SelectEntry } from "../../formulaire/select-entry"; import { I18nService } from "../../services/internationalisation.service"; +import { SelectFieldReference } from "../../formulaire/select-field-reference"; @Component({ selector: "select-field-line", @@ -11,7 +12,7 @@ import { I18nService } from "../../services/internationalisation.service"; "./select-field-line.component.scss" ] }) -export class SelectFieldLineComponent { +export class SelectFieldLineComponent implements OnInit { /** aide en ligne */ protected helpLink: string | { [key: string]: string }; @@ -83,4 +84,11 @@ export class SelectFieldLineComponent { public get uitextOpenHelp() { return this.i18nService.localizeText("INFO_CALCULATOR_OPEN_HELP"); } + + // called every time we navigate to the module + ngOnInit(): void { + if (this._select instanceof SelectFieldReference) { + this._select.updateEntries(); + } + } } diff --git a/src/app/formulaire/definition/concrete/form-solveur.ts b/src/app/formulaire/definition/concrete/form-solveur.ts index 09d2fe6ab..e04fc1665 100644 --- a/src/app/formulaire/definition/concrete/form-solveur.ts +++ b/src/app/formulaire/definition/concrete/form-solveur.ts @@ -1,7 +1,9 @@ -import { IObservable } from "jalhyd"; +import { IObservable, ParamDefinition, Solveur } from "jalhyd"; import { FormulaireBase } from "./form-base"; -import { FieldSet } from "../../fieldset"; +import { SelectFieldNub } from "../../select-field-nub"; +import { SelectFieldParameter } from "../../select-field-parameter"; +import { NgParameter } from "../../ngparam"; /** * Formulaire pour les Solveurs @@ -20,33 +22,73 @@ export class FormulaireSolveur extends FormulaireBase { this._searchedParamSelectId = this.getOption(json, "searchedParamSelectId"); } - public afterParseFieldset(fs: FieldSet) { - if (this._searchedParamSelectId) { - const sel = fs.getFormulaireNodeById(this._searchedParamSelectId); + protected completeParse(json: {}) { + super.completeParse(json); + if (this._targetNubSelectId) { + const sel = this.getFormulaireNodeById(this._targetNubSelectId); if (sel) { - fs.properties.addObserver(this); + sel.addObserver(this); } } - if (this._targetNubSelectId) { - const sel = fs.getFormulaireNodeById(this._targetNubSelectId); + if (this._searchedParamSelectId) { + const sel = this.getFormulaireNodeById(this._searchedParamSelectId); if (sel) { - fs.properties.addObserver(this); + sel.addObserver(this); } } + + } + + private debugState() { + const sol = this._currentNub as Solveur; + const ntc = sol.nubToCalculate; + const spm = sol.searchedParameter; + console.log( + `ETAT:\n X.singleValue=${sol.prms.X.singleValue}\n Y.singleValue=${sol.prms.Y.singleValue}` + + `\n Xinit.singleValue=${sol.prms.Xinit.singleValue}\n Ytarget.singleValue=${sol.prms.Ytarget.singleValue}` + + `\n searchedParam.singleValue=${spm.singleValue}` + ); } // interface Observer public update(sender: IObservable, data: any) { super.update(sender, data); - console.log("FormulaireSolveur().update", sender.constructor.name, data); - if (data.action === "propertyChange") { - if (data.name === "gridType") { - this.reset(); - // Inclined grids have more input fields (OEntH and cIncl) - this.getFieldsetById("fs_grille").updateFields(); - // Alpha and Beta are not always shown - this.getFieldsetById("fs_plan").updateFields(); + if (sender instanceof SelectFieldNub) { + if (data.action === "select") { + // update Solveur property: Nub to calculate + console.log("(i) update Nub to calculate"); + try { + // if searchedParam is set to a value that won't be available anymore + // once nubToCalculate is updated, setPropValue throws an error, but + // nubToCalculate is updated anyway; here, just inhibit the error + this._currentNub.properties.setPropValue("nubToCalculate", data.value.value); + } catch (e) { } + // refresh parameters selector + const sel = this.getFormulaireNodeById(this._searchedParamSelectId) as SelectFieldParameter; + if (sel) { + console.log("(ii) update Parameters entries"); + sel.updateEntries(); + this.debugState(); + // reflect changes in GUI + const inputYtarget = this.getFormulaireNodeById("Ytarget") as NgParameter; + inputYtarget.notifyValueModified(this); + } + } + } + if (sender instanceof SelectFieldParameter) { + if (data.action === "select") { + // update Solveur property: searched Parameter + console.log("(i) update searched Parameter"); + const p: ParamDefinition = data.value.value; + this._currentNub.properties.setPropValue( + "searchedParameter", + p.nubUid + "/" + p.symbol + ); + this.debugState(); + // reflect changes in GUI + const inputXinit = this.getFormulaireNodeById("Xinit") as NgParameter; + inputXinit.notifyValueModified(this); } } } diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts index b178d3a3d..5aa007c8a 100644 --- a/src/app/formulaire/definition/form-definition.ts +++ b/src/app/formulaire/definition/form-definition.ts @@ -452,6 +452,12 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs return new TopFormulaireElementIterator(this); } + /** + * Appelé par CalculatorComponent lrosque le Formulaire est chargé dans la vue, + * c'est à dire lorsqu'on affiche un module de calcul à l'écran + */ + public onCalculatorInit() {} + // interface Observer public update(sender: any, data: any) { diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts index 07c6d3be1..e892c0c2c 100644 --- a/src/app/formulaire/fieldset.ts +++ b/src/app/formulaire/fieldset.ts @@ -21,6 +21,8 @@ import { FormulaireDefinition } from "./definition/form-definition"; import { StringMap } from "../stringmap"; import { FormulaireNode } from "./formulaire-node"; import { FieldsetContainer } from "./fieldset-container"; +import { SelectFieldNub } from "./select-field-nub"; +import { SelectFieldParameter } from "./select-field-parameter"; export class FieldSet extends FormulaireElement implements Observer { /** @@ -97,6 +99,28 @@ export class FieldSet extends FormulaireElement implements Observer { return res; } + private parse_select_reference(json: {}): SelectField { + const refType = json["reference"]; + const source = json["source"]; + let res: SelectField; + if (source === undefined || source === "") { + throw new Error(`Fieldset.parse_select_reference(): "source" must not be empty`); + } + switch (refType) { + case "nub": // @TODO upstreamNub / downstreamNub ? + res = new SelectFieldNub(this, source); + break; + case "parameter": + res = new SelectFieldParameter(this, source); + break; + default: + throw new Error(`Fieldset.parse_select_reference(): unknown reference type ${refType}`); + } + res.parseConfig(json); + res.addObserver(this); + return res; + } + public get properties(): Props { return this.nub.properties; } @@ -186,6 +210,11 @@ export class FieldSet extends FormulaireElement implements Observer { this.addField(param); break; + case "select_reference": + param = this.parse_select_reference(field); + this.addField(param); + break; + } } } @@ -260,7 +289,7 @@ export class FieldSet extends FormulaireElement implements Observer { this.setSelectValueFromProperty("select_regime", "regime"); break; - case "fs_target": // Solveur + /* case "fs_target": // Solveur this.setSelectValueFromProperty("select_target_nub", "nubToCalculate"); break; @@ -274,11 +303,13 @@ export class FieldSet extends FormulaireElement implements Observer { try { selectField.setValue(selectElement); } catch (e) { - console.error(`fieldset.updateFields(): cannot set ${X.parentNub.uid}/${X.symbol} on <select> "select_searched_param"`); + console.error( + `fieldset.updateFields(): cannot set ${X.parentNub.uid}/${X.symbol} on <select> "select_searched_param"` + ); } } } - break; + break; */ } } diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts index 5387c058d..b5d15d216 100644 --- a/src/app/formulaire/ngparam.ts +++ b/src/app/formulaire/ngparam.ts @@ -113,9 +113,8 @@ export class NgParameter extends InputField implements Observer { const cVal = ref.nub.result.getCalculatedValues(); valuePreview = fv(cVal[0]) + " … " + fv(cVal[cVal.length - 1]); } else { - const vCalc = ref.nub.result.vCalc; - if (vCalc) { - valuePreview = fv(vCalc); + if (ref.nub.result.resultElements.length > 0 && ref.nub.result.vCalc) { + valuePreview = fv(ref.nub.result.vCalc); } else { // computation has been run but has failed valuePreview = i18n.localizeText("INFO_PARAMFIELD_CALCULATION_FAILED"); diff --git a/src/app/formulaire/select-field-nub.ts b/src/app/formulaire/select-field-nub.ts new file mode 100644 index 000000000..345699fc1 --- /dev/null +++ b/src/app/formulaire/select-field-nub.ts @@ -0,0 +1,37 @@ +import { SelectFieldReference } from "./select-field-reference"; +import { SelectEntry } from "./select-entry"; +import { ServiceFactory } from "../services/service-factory"; +import { decodeHtml } from "../util"; + +import { Session } from "jalhyd"; + +/** + * A select field that populates itself with references to Nubs + */ +export class SelectFieldNub extends SelectFieldReference { + + protected initSelectedValue() {} + + /** + * Populates entries with available references + */ + protected populate() { + switch (this._source) { + case "solveur_target": // Solveur, paramètre cible (à calculer) + // find all Nubs having at least one link to another Nub's result + const fs = ServiceFactory.instance.formulaireService; + const downstreamNubs = Session.getInstance().getDownstreamNubs(); + for (const dn of downstreamNubs) { + const calc = fs.getFormulaireFromId(dn.uid).calculatorName; + let label = calc; + if (dn.calculatedParam !== undefined) { + const varName = fs.expandVariableName(dn.calcType, dn.calculatedParam.symbol); + label += ` / ${varName} (${dn.calculatedParam.symbol})`; + } + this.addEntry(new SelectEntry(this._entriesBaseId + dn.uid, dn.uid, decodeHtml(label))); + } + break; + } + } + +} diff --git a/src/app/formulaire/select-field-parameter.ts b/src/app/formulaire/select-field-parameter.ts new file mode 100644 index 000000000..d84ad50ac --- /dev/null +++ b/src/app/formulaire/select-field-parameter.ts @@ -0,0 +1,36 @@ +import { SelectFieldReference } from "./select-field-reference"; +import { SelectEntry } from "./select-entry"; +import { decodeHtml } from "../util"; +import { ServiceFactory } from "../services/service-factory"; + +import { Nub, Solveur } from "jalhyd"; + +/** + * A select field that populates itself with references to ParamDefinitions + */ +export class SelectFieldParameter extends SelectFieldReference { + + protected initSelectedValue() {} + + /** + * Populates entries with available references + */ + protected populate() { + switch (this._source) { + case "solveur_searched": // Solveur, paramètre recherché (à faire varier) + // find all non-calculated, non-linked parameters of all Nubs that + // the current "target" Nub depends on (if any) + const fs = ServiceFactory.instance.formulaireService; + const ntc: Nub = (this.parentForm.currentNub as Solveur).nubToCalculate; + const searchableParams = Solveur.getDependingNubsSearchableParams(ntc); + for (const p of searchableParams) { + const calc = fs.getFormulaireFromId(p.parentNub.uid).calculatorName; + const varName = fs.expandVariableName(p.parentNub.calcType, p.symbol); + const label = `${p.symbol} - ${varName} (${calc})`; + this.addEntry(new SelectEntry(this._entriesBaseId + p.nubUid + "_" + p.symbol, p, decodeHtml(label))); + } + break; + } + } + +} diff --git a/src/app/formulaire/select-field-reference.ts b/src/app/formulaire/select-field-reference.ts new file mode 100644 index 000000000..a84b272ea --- /dev/null +++ b/src/app/formulaire/select-field-reference.ts @@ -0,0 +1,92 @@ +import { SelectField } from "./select-field"; +import { SelectEntry } from "./select-entry"; +import { FormulaireNode } from "./formulaire-node"; + +/** + * A select field that populates itself with references to + * available objects (for ex. Nub or ParamDefinition) + */ +export abstract class SelectFieldReference extends SelectField { + + /** source identifier for populate() method */ + protected _source: string; + + constructor(parent: FormulaireNode, source: string) { + super(parent); + this._source = source; + this.initSelectedValue(); + } + + protected abstract initSelectedValue(); + + /** + * Populates entries with available references + */ + protected abstract populate(); + + /** + * Reloads available entries, trying to keep the current selected + * value; does not notify observers if value did not change + */ + public updateEntries() { + // store previous selected entry + const pse = this._selectedEntry; + // empty + this.clearEntries(); + // populate + this.populate(); + // keep previously selected entry if possible + if (pse && pse.id) { + this.setValueFromId(pse.id); + } + // if no entry is available anymore, unset value + if (this.entries.length === 0) { + super.setValue(undefined); + } + } + + /** + * Updates selectedValue; notifies observers only if + * value.id has changed + */ + public setValue(v: SelectEntry) { + const previousSelectedEntry = this._selectedEntry; + this._selectedEntry = v; + if ( + ! previousSelectedEntry + || (previousSelectedEntry.id !== v.id) + ) { + console.log(`--> select, setValue: ${v.value}`); + this.notifyObservers({ + "action": "select", + "value": v + }, this); + } + } + + /** + * Sets value from given ID; if it was not found, sets the + * first available entry as selectedValue + */ + public setValueFromId(id: string) { + let found = false; + for (const e of this._entries) { + if (e.id === id) { + found = true; + this.setValue(e); + } + } + if (! found) { + // default to first available entry if any + if (this._entries.length > 0) { + this.setValue(this._entries[0]); + } else { + // notify observers that no value is selected anymore + this.notifyObservers({ + "action": "select", + "value": undefined + }, this); + } + } + } +} diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts index 065b09633..66545a058 100644 --- a/src/app/formulaire/select-field.ts +++ b/src/app/formulaire/select-field.ts @@ -108,7 +108,9 @@ export class SelectField extends Field { public updateLocalisation(loc: StringMap) { super.updateLocalisation(loc); for (const e of this._entries) { - e.label = loc[e.id]; + if (loc[e.id] !== undefined) { + e.label = loc[e.id]; + } } } @@ -191,26 +193,6 @@ export class SelectField extends Field { this.addEntry(new SelectEntry(this._entriesBaseId + BiefRegime.Fluvial, BiefRegime.Fluvial)); this.addEntry(new SelectEntry(this._entriesBaseId + BiefRegime.Torrentiel, BiefRegime.Torrentiel)); break; - - case "solveur_target": // Solveur, paramètre cible (à calculer) - // find all Nubs having at least one link to another Nub's result - console.log(">> update solveur targets"); - const downstreamNubs = Session.getInstance().getDownstreamNubs(); - for (const dn of downstreamNubs) { - this.addEntry(new SelectEntry(this._entriesBaseId + dn.uid, dn.uid)); - } - break; - - case "solveur_searched": // Solveur, paramètre recherché (à faire varier) - // find all non-calculated, non-linked parameters of all Nubs that - // the current "target" Nub depends on (if any) - console.log(">> update solveur searched"); - const ntc: Nub = (nub as Solveur).nubToCalculate; - const searchableParams = Solveur.getDependingNubsSearchableParams(ntc); - for (const p of searchableParams) { - this.addEntry(new SelectEntry(this._entriesBaseId + p.nubUid + "_" + p.symbol, p)); - } - break; } } } diff --git a/src/app/util.ts b/src/app/util.ts index 6d6a10bb1..e4d3e1f1b 100644 --- a/src/app/util.ts +++ b/src/app/util.ts @@ -30,3 +30,14 @@ export function fv(p: NgParameter | number): string { return formattedValue(value, nDigits); } + +/** + * Trick to decode HTML entities in a string + * https://stackoverflow.com/a/7394787/5986614 + * @param html string containing HTML entities, like + */ +export function decodeHtml(html: string): string { + const txt = document.createElement("textarea"); + txt.innerHTML = html; + return txt.value; +} diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index ad74567f5..270145ca4 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -4,7 +4,7 @@ "WARNING_DOWNSTREAM_ELEVATION_POSSIBLE_SUBMERSION": "Downstream elevation is higher than weir elevation (possible submersion)", "WARNING_NOTCH_SUBMERSION_GREATER_THAN_07": "Notch formula is discouraged when submersion is greater than 0.7", "WARNING_SLOT_SUBMERSION_NOT_BETWEEN_07_AND_09": "Slot formula is discouraged when submersion is lower than 0.7 or greater than 0.9", - "ERROR_ABSTRACT": "%nb% errors occurred during calculation", + "WARNING_ERRORS_ABSTRACT": "%nb% errors occurred during calculation", "ERROR_BIEF_Z1_CALC_FAILED": "Unable to calculate upstream elevation (calculation interrupted before upstream)", "ERROR_BIEF_Z2_CALC_FAILED": "Unable to calculate downstream elevation (calculation interrupted before downstream)", "ERROR_DICHO_CONVERGE": "Dichotomy could not converge", @@ -15,6 +15,8 @@ "ERROR_DICHO_TARGET_TOO_HIGH": "Dichotomy: the solution %targetSymbol%=%targetValue% is greater than the maximum computable value %targetSymbol%(%variableSymbol%=%variableExtremeValue%)=%extremeTarget%)", "ERROR_DICHO_TARGET_TOO_LOW": "Dichotomy: the solution %targetSymbol%=%targetValue% is lower than the minimum computable value %targetSymbol%(%variableSymbol%=%variableExtremeValue%)=%extremeTarget%)", "ERROR_ELEVATION_ZI_LOWER_THAN_Z2": "Upstream elevation is lower than downstream elevation", + "ERROR_IN_CALC_CHAIN": "An error occurred in calculation chain", + "WARNING_ERROR_IN_CALC_CHAIN_STEPS": "Errors occurred during chain calculation", "ERROR_INTERVAL_OUTSIDE": "Interval: value %value% is outside of %interval%", "ERROR_INTERVAL_UNDEF": "Interval: invalid 'undefined' value", "ERROR_INVALID_AT_POSITION": "Position %s:", @@ -80,6 +82,8 @@ "INFO_COURBEREMOUS_TITRE": "Backwater curves", "INFO_DEVER_TITRE_COURT": "Free weir", "INFO_DEVER_TITRE": "Free flow weir stage-discharge laws", + "INFO_DIAGRAM_SOLVEUR_FINDS": "finds", + "INFO_DIAGRAM_SOLVEUR_READS": "reads", "INFO_DIAGRAM_TITLE": "Calculation modules diagram", "INFO_DIAGRAM_DRAWING_ERROR": "Error while drawing diagram", "INFO_DIAGRAM_CALCULATED_PARAM": "calculated parameter", @@ -455,7 +459,7 @@ "INFO_EXAMPLE_LABEL_PAB_COMPLETE": "Standard fish ladder", "INFO_EXAMPLES_TITLE": "Examples", "INFO_EXAMPLES_SUBTITLE": "Load standard examples", - "WARNING_ABSTRACT": "%nb% warnings occurred during calculation", + "WARNING_WARNINGS_ABSTRACT": "%nb% warnings occurred during calculation", "WARNING_REMOUS_ARRET_CRITIQUE": "Calculation stopped: critical elevation reached at abscissa %x%", "WARNING_STRUCTUREKIVI_HP_TROP_ELEVE": "h/p must not be greater than 2.5. h/p is forced to 2.5", "WARNING_STRUCTUREKIVI_PELLE_TROP_FAIBLE": "Threshold height should be greater than 0.1 m. Beta coefficient is forced to 0", @@ -468,5 +472,6 @@ "WARNING_DOWNSTREAM_BOTTOM_HIGHER_THAN_WATER": "Downstream water elevation is lower or equal to bottom elevation", "WARNING_YN_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "Normal depth: slope is negative or zero, normal depth is infinite", "WARNING_YN_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE": "Normal depth: non convergence of the calculation (Newton's method)", - "WARNING_SESSION_LOAD_NOTES_MERGED": "Notes have been merged" + "WARNING_SESSION_LOAD_NOTES_MERGED": "Notes have been merged", + "WARNING_VALUE_ROUNDED_TO_INTEGER": "Value of %symbol% was rounded to %rounded%" } diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index e93d09b95..e04f71c07 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -4,7 +4,7 @@ "WARNING_DOWNSTREAM_ELEVATION_POSSIBLE_SUBMERSION": "La cote de l'eau aval est plus élevée que la cote du seuil (ennoiement possible)", "WARNING_NOTCH_SUBMERSION_GREATER_THAN_07": "La formule de l'échancrure n'est pas conseillée pour un ennoiement supérieur à 0.7", "WARNING_SLOT_SUBMERSION_NOT_BETWEEN_07_AND_09": "La formule de la fente n'est pas conseillée pour un ennoiement inférieur à 0.7 et supérieur à 0.9", - "ERROR_ABSTRACT": "%nb% erreurs rencontrées lors du calcul", + "WARNING_ERRORS_ABSTRACT": "%nb% erreurs rencontrées lors du calcul", "ERROR_BIEF_Z1_CALC_FAILED": "Impossible de calculer la cote amont (calcul interrompu avant l'amont)", "ERROR_BIEF_Z2_CALC_FAILED": "Impossible de calculer la cote aval (calcul interrompu avant l'aval)", "ERROR_DICHO_CONVERGE": "La dichotomie n'a pas pu converger", @@ -15,6 +15,8 @@ "ERROR_DICHO_TARGET_TOO_HIGH": "Dichotomie : la solution %targetSymbol%=%targetValue% est supérieure à la valeur maximale calculable %targetSymbol%(%variableSymbol%=%variableExtremeValue%)=%extremeTarget%)", "ERROR_DICHO_TARGET_TOO_LOW": "Dichotomie : la solution %targetSymbol%=%targetValue% est inférieure à la valeur minimale calculable %targetSymbol%(%variableSymbol%=%variableExtremeValue%)=%extremeTarget%)", "ERROR_ELEVATION_ZI_LOWER_THAN_Z2": "La cote amont est plus basse que la cote aval", + "ERROR_IN_CALC_CHAIN": "Une erreur est survenue dans la chaîne de calcul", + "WARNING_ERROR_IN_CALC_CHAIN_STEPS": "Des erreurs sont survenues durant le calcul en chaîne", "ERROR_INTERVAL_OUTSIDE": "Intervalle : la valeur %value% est hors de l'intervalle %interval%", "ERROR_INTERVAL_UNDEF": "Interval : valeur 'undefined' incorrecte", "ERROR_INVALID_AT_POSITION": "Position %s :", @@ -80,6 +82,8 @@ "INFO_COURBEREMOUS_TITRE": "Courbes de remous", "INFO_DEVER_TITRE_COURT": "Déver. dénoyés", "INFO_DEVER_TITRE": "Lois de déversoirs dénoyés", + "INFO_DIAGRAM_SOLVEUR_FINDS": "trouve", + "INFO_DIAGRAM_SOLVEUR_READS": "lit", "INFO_DIAGRAM_TITLE": "Diagramme des modules de calcul", "INFO_DIAGRAM_DRAWING_ERROR": "Erreur lors du dessin du diagramme", "INFO_DIAGRAM_CALCULATED_PARAM": "paramètre calculé", @@ -454,7 +458,7 @@ "INFO_EXAMPLE_LABEL_PAB_COMPLETE": "Passe à bassins type", "INFO_EXAMPLES_TITLE": "Exemples", "INFO_EXAMPLES_SUBTITLE": "Charger des exemples types", - "WARNING_ABSTRACT": "%nb% avertissements rencontrés lors du calcul", + "WARNING_WARNINGS_ABSTRACT": "%nb% avertissements rencontrés lors du calcul", "WARNING_REMOUS_ARRET_CRITIQUE": "Arrêt du calcul : hauteur critique atteinte à l'abscisse %x%", "WARNING_STRUCTUREKIVI_HP_TROP_ELEVE": "h/p ne doit pas être supérieur à 2,5. h/p est forcé à 2,5", "WARNING_STRUCTUREKIVI_PELLE_TROP_FAIBLE": "La pelle du seuil doit mesurer au moins 0,1 m. Le coefficient béta est forcé à 0", @@ -467,5 +471,6 @@ "WARNING_DOWNSTREAM_BOTTOM_HIGHER_THAN_WATER": "La cote de l'eau à l'aval est plus basse ou égale à la cote de fond", "WARNING_YN_SECTION_PENTE_NEG_NULLE_HNORMALE_INF": "Hauteur normale: pente négative ou nulle, hauteur normale infinie", "WARNING_YN_SECTION_NON_CONVERGENCE_NEWTON_HNORMALE": "Hauteur normale: non convergence du calcul (méthode de Newton)", - "WARNING_SESSION_LOAD_NOTES_MERGED": "Les notes ont été fusionnées" + "WARNING_SESSION_LOAD_NOTES_MERGED": "Les notes ont été fusionnées", + "WARNING_VALUE_ROUNDED_TO_INTEGER": "La valeur de %symbol% a été arrondie à %rounded%" } -- GitLab