From 1f581c46ecef3a7d9cc0ba130793431d989aa0b7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 2 Apr 2022 18:17:09 +0200 Subject: [PATCH 001/436] Adding thanks to popup --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 5 + .../LogarithmPlotter/LogarithmPlotter.qml | 2 + .../LogarithmPlotter/Popup/ThanksTo.qml | 320 ++++++++++++++++++ .../eu/ad5001/LogarithmPlotter/Popup/qmldir | 2 +- .../ad5001/LogarithmPlotter/js/expr-eval.js | 6 +- README.md | 6 + 6 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 194b058..c7aa7bb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -169,6 +169,11 @@ MenuBar { onTriggered: Qt.openUrlExternally("https://hosted.weblate.org/engage/logarithmplotter/") } MenuSeparator { } + Action { + text: qsTr("&Thanks") + icon.name: 'about' + onTriggered: thanksTo.open() + } Action { text: qsTr("&About") shortcut: StandardKey.HelpContents diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index b2f6975..3a53be3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -59,6 +59,8 @@ ApplicationWindow { Popup.About {id: about} + Popup.ThanksTo {id: thanksTo} + Popup.Alert { id: alert anchors.bottom: parent.bottom diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml new file mode 100644 index 0000000..fce6d1c --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -0,0 +1,320 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.12 +import QtQuick.Dialogs 1.3 as D +import QtQuick.Controls 2.12 + +/*! + \qmltype ThanksTo + \inqmlmodule eu.ad5001.LogarithmPlotter.Popup + \brief Thanks to popup of LogarithmPlotter. + + \sa LogarithmPlotter +*/ +D.Dialog { + id: about + title: qsTr("Thanks and Contributions - LogarithmPlotter") + width: 400 + height: 600 + + Column { + anchors.fill: parent + spacing: 10 + + ListView { + id: librariesListView + anchors.left: parent.left + width: parent.width + //height: parent.height + implicitHeight: contentItem.childrenRect.height + + model: ListModel { + Component.onCompleted: { + append({ + libName: 'expr-eval', + license: 'MIT', + licenseLink: 'https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt', + linkName: qsTr('Source code'), + link: 'https://github.com/silentmatt/expr-eval', + authors: [{ + authorLine: qsTr('Original library by Raphael Graf'), + email: 'r@undefined.ch', + website: 'https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html', + websiteName: qsTr('Source') + }, { + authorLine: qsTr('Ported to Javascript by Matthew Crumley'), + email: 'email@matthewcrumley.com', + website: 'https://silentmatt.com/', + websiteName: qsTr('Website') + }, { + authorLine: qsTr('Ported to QMLJS by Ad5001'), + email: 'mail@ad5001.eu', + website: 'https://ad5001.eu/', + websiteName: qsTr('Website') + }] + }) + } + } + + header: Label { + id: librariesUsedHeader + wrapMode: Text.WordWrap + font.pixelSize: 25 + text: qsTr("Libraries included") + height: implicitHeight + 10 + } + + delegate: Column { + id: libClmn + width: librariesListView.width + spacing: 10 + + Item { + height: libraryHeader.height + width: parent.width + + Label { + id: libraryHeader + anchors.left: parent.left + wrapMode: Text.WordWrap + font.pixelSize: 18 + text: libName + } + + Row { + anchors.right: parent.right + height: parent.height + spacing: 10 + + Button { + height: parent.height + text: license + icon.name: 'license' + onClicked: Qt.openUrlExternally(licenseLink) + } + + Button { + height: parent.height + text: linkName + icon.name: 'web-browser' + onClicked: Qt.openUrlExternally(link) + } + } + } + + ListView { + id: libAuthors + anchors.left: parent.left + anchors.leftMargin: 10 + model: authors + width: parent.width - 10 + implicitHeight: contentItem.childrenRect.height + + delegate: Item { + id: libAuthor + width: librariesListView.width - 10 + height: 50 + + Label { + id: libAuthorName + anchors.left: parent.left + anchors.right: buttons.left + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + font.pixelSize: 14 + text: authorLine + } + + Row { + id: buttons + anchors.right: parent.right + height: parent.height + spacing: 10 + + Button { + anchors.verticalCenter: parent.verticalCenter + text: websiteName + icon.name: 'web-browser' + height: parent.height - 10 + onClicked: Qt.openUrlExternally(website) + } + + Button { + anchors.verticalCenter: parent.verticalCenter + text: qsTr('Email') + icon.name: 'email' + height: parent.height - 10 + onClicked: Qt.openUrlExternally('mailto:' + email) + } + } + } + } + + Rectangle { + id: libSeparator + opacity: 0.3 + color: sysPalette.windowText + width: parent.width + height: 1 + } + } + } + + ListView { + id: translationsListView + anchors.left: parent.left + width: parent.width + implicitHeight: contentItem.childrenRect.height + spacing: 3 + + + model: ListModel { + Component.onCompleted: { + append({ + tranName: '🇬🇧 ' + qsTr('English'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/', + authors: [{ + authorLine: 'Ad5001', + email: 'mail@ad5001.eu', + website: 'https://ad5001.eu', + websiteName: qsTr('Website') + }] + }) + append({ + tranName: '🇫🇷 ' + qsTr('French'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/', + authors: [{ + authorLine: 'Ad5001', + website: 'https://ad5001.eu', + websiteName: qsTr('Website') + }] + }) + append({ + tranName: '🇩🇪 ' + qsTr('German'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/', + authors: [{ + authorLine: 'Ad5001', + website: 'https://ad5001.eu', + websiteName: qsTr('Website') + }] + }) + append({ + tranName: '🇭🇺 ' + qsTr('Hungarian'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/', + authors: [{ + authorLine: 'Óvári', + website: 'https://github.com/ovari', + websiteName: qsTr('Github') + }] + }) + append({ + tranName: '🇳🇴 ' + qsTr('Norwegian'), + link: 'https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/no/', + authors: [{ + authorLine: 'Allan Nordhøy', + website: 'https://github.com/comradekingu', + websiteName: qsTr('Github') + }] + }) + } + } + + header: Label { + id: translationsHeader + wrapMode: Text.WordWrap + font.pixelSize: 25 + text: qsTr("Translations included") + height: implicitHeight + 10 + } + + delegate: Column { + id: tranClmn + width: translationsListView.width + + Item { + width: parent.width + height: translationHeader.height + 10 + + Label { + id: translationHeader + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + font.pixelSize: 18 + text: tranName + } + + Row { + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + height: 30 + spacing: 10 + + Button { + height: parent.height + text: qsTr('Improve') + icon.name: 'web-browser' + onClicked: Qt.openUrlExternally(link) + } + } + } + + ListView { + id: tranAuthors + anchors.left: parent.left + anchors.leftMargin: 10 + model: authors + width: parent.width - 10 + implicitHeight: contentItem.childrenRect.height + + delegate: Item { + id: tranAuthor + width: tranAuthors.width + height: 40 + + Label { + id: tranAuthorName + anchors.left: parent.left + anchors.right: buttons.left + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + font.pixelSize: 14 + text: authorLine + } + + Row { + id: buttons + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + height: 30 + spacing: 10 + + Button { + text: websiteName + icon.name: 'web-browser' + height: parent.height + onClicked: Qt.openUrlExternally(website) + } + } + } + } + } + } + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir index a37ae7c..3f71a18 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir @@ -5,4 +5,4 @@ Alert 1.0 Alert.qml FileDialog 1.0 FileDialog.qml GreetScreen 1.0 GreetScreen.qml Changelog 1.0 Changelog.qml - +ThanksTo 1.0 ThanksTo.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 9192db5..9253edc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -1826,10 +1826,12 @@ Parser.prototype.isOperatorEnabled = function (op) { }; /*! - Based on ndef.parser, by Raphael Graf(r@undefined.ch) + Based on ndef.parser, by Raphael Graf http://www.undefined.ch/mparser/index.html - Ported to JavaScript and modified by Matthew Crumley (email@matthewcrumley.com, http://silentmatt.com/) + Ported to JavaScript and modified by Matthew Crumley (http://silentmatt.com/) + + Ported to QMLJS with modifications done accordingly done by Ad5001 (https://ad5001.eu) You are free to use and modify this code in anyway you find useful. Please leave this comment in the code to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code, diff --git a/README.md b/README.md index 7c9e14f..bb99c41 100644 --- a/README.md +++ b/README.md @@ -74,3 +74,9 @@ There are several ways to contribute to LogarithmPlotter. Language files translations located at LogarithmPlotter/i18n are licensed under GNU GPL3.0+ and are copyrighted by their original authors. See LICENSE.md for more details: - 🇳🇴 Norwegian translation by [Allan Nordhøy](https://github.com/comradekingu) - 🇭🇺 Hungarian translation by [Óvári](https://github.com/ovari) + +### Libraries used + +LogarithmPlotter includes [expr-eval](https://github.com/silentmatt/expr-eval) a port of [ndef.parser](https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html) by Raphael Graf <r@undefined.ch>, ported to javascript by Matthew Crumley <email@matthewcrumley.com> (http://silentmatt.com/), and then to QMLJS by Ad5001. + +The code is licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). From 3a2fcb1be1325650b70260ab3a5523899cdf080e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 16 Apr 2022 19:25:01 +0200 Subject: [PATCH 002/436] Adding new translations strings. --- LogarithmPlotter/i18n/lp_de.ts | 134 +++++++++++++++++++++++---- LogarithmPlotter/i18n/lp_en.ts | 134 +++++++++++++++++++++++---- LogarithmPlotter/i18n/lp_es.ts | 134 +++++++++++++++++++++++---- LogarithmPlotter/i18n/lp_fr.ts | 134 +++++++++++++++++++++++---- LogarithmPlotter/i18n/lp_hu.ts | 134 +++++++++++++++++++++++---- LogarithmPlotter/i18n/lp_nb_NO.ts | 134 +++++++++++++++++++++++---- LogarithmPlotter/i18n/lp_template.ts | 134 +++++++++++++++++++++++---- 7 files changed, 812 insertions(+), 126 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 27f5bca..0101fa4 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -134,16 +134,21 @@ + &Thanks + + + + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -297,62 +302,62 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter - + Objects Objekte - + Settings Einstellungen - + History Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not save file: Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -514,6 +519,99 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Grafik laden + + ThanksTo + + + Thanks and Contributions - LogarithmPlotter + + + + + Source code + + + + + Original library by Raphael Graf + + + + + Source + + + + + Ported to Javascript by Matthew Crumley + + + + + + + + + Website + + + + + Ported to QMLJS by Ad5001 + + + + + Libraries included + + + + + Email + + + + + English + + + + + French + + + + + German + + + + + Hungarian + + + + + + Github + + + + + Norwegian + + + + + Translations included + + + + + Improve + + + changelog @@ -674,19 +772,19 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -695,7 +793,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index e7e90ae..9bd3e79 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -134,16 +134,21 @@ + &Thanks + + + + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -297,62 +302,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects Objects - + Settings Settings - + History History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not save file: Could not save file: - + Loaded file '%1'. Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -514,6 +519,99 @@ These settings can be changed at any time from the "Settings" menu.Open plot + + ThanksTo + + + Thanks and Contributions - LogarithmPlotter + + + + + Source code + + + + + Original library by Raphael Graf + + + + + Source + + + + + Ported to Javascript by Matthew Crumley + + + + + + + + + Website + + + + + Ported to QMLJS by Ad5001 + + + + + Libraries included + + + + + Email + + + + + English + + + + + French + + + + + German + + + + + Hungarian + + + + + + Github + + + + + Norwegian + + + + + Translations included + + + + + Improve + + + changelog @@ -674,7 +772,7 @@ These settings can be changed at any time from the "Settings" menu. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -683,12 +781,12 @@ If you already have a latex distribution installed, make sure it's installe Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -701,7 +799,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index d17ef46..d0e5cad 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -134,16 +134,21 @@ + &Thanks + + + + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -296,62 +301,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects - + Settings - + History - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -513,6 +518,99 @@ These settings can be changed at any time from the "Settings" menu. + + ThanksTo + + + Thanks and Contributions - LogarithmPlotter + + + + + Source code + + + + + Original library by Raphael Graf + + + + + Source + + + + + Ported to Javascript by Matthew Crumley + + + + + + + + + Website + + + + + Ported to QMLJS by Ad5001 + + + + + Libraries included + + + + + Email + + + + + English + + + + + French + + + + + German + + + + + Hungarian + + + + + + Github + + + + + Norwegian + + + + + Translations included + + + + + Improve + + + changelog @@ -646,19 +744,19 @@ These settings can be changed at any time from the "Settings" menu. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -667,7 +765,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 32830c4..629bdfb 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -135,16 +135,21 @@ + &Thanks + + + + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -305,62 +310,62 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter - + Objects Objets - + Settings Paramètres - + History Historique - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not save file: Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -522,6 +527,99 @@ These settings can always be changed at any time from the "Settings" m Ouvrir un graphe + + ThanksTo + + + Thanks and Contributions - LogarithmPlotter + + + + + Source code + + + + + Original library by Raphael Graf + + + + + Source + + + + + Ported to Javascript by Matthew Crumley + + + + + + + + + Website + + + + + Ported to QMLJS by Ad5001 + + + + + Libraries included + + + + + Email + + + + + English + + + + + French + + + + + German + + + + + Hungarian + + + + + + Github + + + + + Norwegian + + + + + Translations included + + + + + Improve + + + changelog @@ -683,7 +781,7 @@ These settings can always be changed at any time from the "Settings" m latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -692,12 +790,12 @@ Si vous avez déjà installé une distribution Latex, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution Latex comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution Latex. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -710,7 +808,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de latex est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 91ba500..d49c7ac 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -134,16 +134,21 @@ + &Thanks + + + + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -297,62 +302,62 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter - + Objects Tárgyak - + Settings Beállítások - + History Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not save file: A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -514,6 +519,99 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Ábra betöltése + + ThanksTo + + + Thanks and Contributions - LogarithmPlotter + + + + + Source code + + + + + Original library by Raphael Graf + + + + + Source + + + + + Ported to Javascript by Matthew Crumley + + + + + + + + + Website + + + + + Ported to QMLJS by Ad5001 + + + + + Libraries included + + + + + Email + + + + + English + + + + + French + + + + + German + + + + + Hungarian + + + + + + Github + + + + + Norwegian + + + + + Translations included + + + + + Improve + + + changelog @@ -670,19 +768,19 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -691,7 +789,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 85ade3d..f1191ee 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -134,16 +134,21 @@ + &Thanks + + + + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -297,62 +302,62 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. LogarithmPlotter - + Objects Objekter - + Settings Innstillinger - + History Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not save file: Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -514,6 +519,99 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Last inn plott + + ThanksTo + + + Thanks and Contributions - LogarithmPlotter + + + + + Source code + + + + + Original library by Raphael Graf + + + + + Source + + + + + Ported to Javascript by Matthew Crumley + + + + + + + + + Website + + + + + Ported to QMLJS by Ad5001 + + + + + Libraries included + + + + + Email + + + + + English + + + + + French + + + + + German + + + + + Hungarian + + + + + + Github + + + + + Norwegian + + + + + Translations included + + + + + Improve + + + changelog @@ -670,19 +768,19 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -691,7 +789,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index aacd4e5..506d6a7 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -134,16 +134,21 @@ + &Thanks + + + + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -296,62 +301,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects - + Settings - + History - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -513,6 +518,99 @@ These settings can be changed at any time from the "Settings" menu. + + ThanksTo + + + Thanks and Contributions - LogarithmPlotter + + + + + Source code + + + + + Original library by Raphael Graf + + + + + Source + + + + + Ported to Javascript by Matthew Crumley + + + + + + + + + Website + + + + + Ported to QMLJS by Ad5001 + + + + + Libraries included + + + + + Email + + + + + English + + + + + French + + + + + German + + + + + Hungarian + + + + + + Github + + + + + Norwegian + + + + + Translations included + + + + + Improve + + + changelog @@ -646,19 +744,19 @@ These settings can be changed at any time from the "Settings" menu. latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -667,7 +765,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} From ff10b87b8ba340755d1d966d4c2074b1e0f79002 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 16 Apr 2022 17:30:02 +0000 Subject: [PATCH 003/436] Translated using Weblate (English) Currently translated at 100.0% (187 of 187 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index e7e90ae..6d6083f 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -100,7 +100,7 @@ Enable LaTeX rendering - + Enable LaTeX rendering @@ -245,7 +245,7 @@ These settings can be changed at any time from the "Settings" menu. Enable LaTeX rendering - + Enable LaTeX rendering @@ -561,7 +561,7 @@ These settings can be changed at any time from the "Settings" menu. If you have latex enabled, you can use use latex markup in between $$ to create equations. - + If you have latex enabled, you can use use latex markup in between $$ to create equations. From 1b91176f2d4787dcd75ed3d7c09fd30f11d86fdc Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 16 Apr 2022 17:35:06 +0000 Subject: [PATCH 004/436] Translated using Weblate (English) Currently translated at 100.0% (205 of 205 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 60 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 9bd3e79..e49fa7b 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -100,7 +100,7 @@ Enable LaTeX rendering - + Enable LaTeX rendering @@ -135,7 +135,7 @@ &Thanks - + &Thanks @@ -250,7 +250,7 @@ These settings can be changed at any time from the "Settings" menu. Enable LaTeX rendering - + Enable LaTeX rendering @@ -524,27 +524,27 @@ These settings can be changed at any time from the "Settings" menu. Thanks and Contributions - LogarithmPlotter - + Thanks and Contributions - LogarithmPlotter Source code - + Source code Original library by Raphael Graf - + Original library by Raphael Graf Source - + Source Ported to Javascript by Matthew Crumley - + Ported to Javascript by Matthew Crumley @@ -553,63 +553,63 @@ These settings can be changed at any time from the "Settings" menu. Website - + Website Ported to QMLJS by Ad5001 - + Ported to QMLJS by Ad5001 Libraries included - + Libraries included Email - + Email English - + English French - + French German - + German Hungarian - + Hungarian Github - + Github Norwegian - + Norwegian Translations included - + Translations included Improve - + Improve @@ -659,7 +659,7 @@ These settings can be changed at any time from the "Settings" menu. If you have latex enabled, you can use use latex markup in between $$ to create equations. - + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -776,14 +776,14 @@ These settings can be changed at any time from the "Settings" menu.No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - No Latex installation found. -If you already have a latex distribution installed, make sure it's installed on your path. -Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. + No LaTeX installation found. +If you already have a LaTeX distribution installed, make sure it's installed on your path. +Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.org/texlive/. DVIPNG was not found. Make sure you include it from your Latex distribution. - DVIPNG was not found. Make sure you include it from your Latex distribution. + DVIPNG was not found. Make sure you include it from your LaTeX distribution. @@ -792,11 +792,11 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - An exception occurred within the creation of the latex formula. + An exception occurred within the creation of the LaTeX formula. Process '{}' ended with a non-zero return code {}: {} -Please make sure your latex installation is correct and report a bug if so. +Please make sure your LaTeX installation is correct and report a bug if so. @@ -804,10 +804,10 @@ Please make sure your latex installation is correct and report a bug if so. - An exception occurred within the creation of the latex formula. + An exception occurred within the creation of the LaTeX formula. Process '{}' took too long to finish: {} -Please make sure your latex installation is correct and report a bug if so. +Please make sure your LaTeX installation is correct and report a bug if so. @@ -1081,7 +1081,7 @@ Please make sure your latex installation is correct and report a bug if so. disableLatex - Disable latex rendering for this text + Disable LaTeX rendering for this text From b69aaa2d7a41cb31680b4e3b57b7b3efde8fa032 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 16 Apr 2022 17:47:49 +0000 Subject: [PATCH 005/436] Translated using Weblate (German) Currently translated at 100.0% (205 of 205 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 61 +++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 0101fa4..74ddf5c 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -100,7 +100,7 @@ Enable LaTeX rendering - + LaTeX-Rendering aktivieren @@ -135,7 +135,7 @@ &Thanks - + &Danksagungen @@ -250,7 +250,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Enable LaTeX rendering - + LaTeX-Rendering aktivieren @@ -524,27 +524,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Thanks and Contributions - LogarithmPlotter - + Danksagungen und Beiträge - LogarithmPlotter Source code - + Quellcode Original library by Raphael Graf - + Originalbibliothek von Raphael Graf Source - + Quelle Ported to Javascript by Matthew Crumley - + Portiert auf Javascript von Matthew Crumley @@ -553,63 +553,63 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Website - + Website Ported to QMLJS by Ad5001 - + Portiert auf QMLJS von Ad5001 Libraries included - + Einschließlich Bibliotheken Email - + E-Mail English - + Englisch French - + Französisch German - + Deutsch Hungarian - + Ungarisch Github - + Github Norwegian - + Norwegisch Translations included - + Einschließlich Übersetzungen Improve - + Verbessern @@ -659,7 +659,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" If you have latex enabled, you can use use latex markup in between $$ to create equations. - + Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -776,12 +776,14 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + Keine LaTeX-Installation gefunden. +Wenn Sie bereits eine LaTeX-Distribution installiert haben, vergewissern Sie sich, dass sie in Ihrem Pfad installiert ist. +Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.org/texlive/ herunterladen. DVIPNG was not found. Make sure you include it from your Latex distribution. - + DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. @@ -790,7 +792,11 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + Bei der Erstellung der LaTeX-Formel ist eine Exception aufgetreten. +Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet {}: + +{} +Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. @@ -798,7 +804,10 @@ Please make sure your latex installation is correct and report a bug if so. - + Bei der Erstellung der LaTeX-Formel ist eine Exception aufgetreten. +Der Prozess '{}' brauchte zu lange, um beendet zu werden: +{} +Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. @@ -1072,7 +1081,7 @@ Please make sure your latex installation is correct and report a bug if so. disableLatex - + LaTeX-Rendering für diesen Text deaktivieren From 6129bcf928665206f55412e146e75c31cb12f296 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 16 Apr 2022 18:01:53 +0000 Subject: [PATCH 006/436] Translated using Weblate (French) Currently translated at 100.0% (205 of 205 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 60 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 629bdfb..35ee738 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -101,7 +101,7 @@ Enable LaTeX rendering - + Activer le rendu LaTeX @@ -136,7 +136,7 @@ &Thanks - + &Remerciements @@ -242,7 +242,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Enable LaTeX rendering - + Activer le rendu LaTeX @@ -532,27 +532,27 @@ These settings can always be changed at any time from the "Settings" m Thanks and Contributions - LogarithmPlotter - + Remerciements et contributions - LogarithmPlotter Source code - + Code source Original library by Raphael Graf - + Bibliothèque originale de Raphael Graf Source - + Source Ported to Javascript by Matthew Crumley - + Porté en Javascript par Matthew Crumley @@ -561,63 +561,63 @@ These settings can always be changed at any time from the "Settings" m Website - + Site web Ported to QMLJS by Ad5001 - + Porté à QMLJS par Ad5001 Libraries included - + Bibliothèques incluses Email - + Email English - + Anglais French - + Français German - + Allemand Hungarian - + Hongrois Github - + Github Norwegian - + Norvégien Translations included - + Traductions incluses Improve - + Améliorer @@ -668,7 +668,7 @@ These settings can always be changed at any time from the "Settings" m If you have latex enabled, you can use use latex markup in between $$ to create equations. - + Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -785,14 +785,14 @@ These settings can always be changed at any time from the "Settings" m No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - Aucune installation de Latex trouvée. -Si vous avez déjà installé une distribution Latex, assurez-vous qu'elle est installée sur votre PATH. -Sinon, vous pouvez télécharger une distribution Latex comme TeX Live à l'adresse https://tug.org/texlive/. + Aucune installation de LaTeX trouvée. +Si vous avez déjà installé une distribution LaTeX, assurez-vous qu'elle est installée sur votre PATH. +Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l'adresse https://tug.org/texlive/. DVIPNG was not found. Make sure you include it from your Latex distribution. - DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution Latex. + DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. @@ -801,11 +801,11 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - Une exception s'est produite lors de la création de la formule latex. + Une exception s'est produite lors de la création de la formule LaTeX. Le processus '{}' s'est terminé par un code de retour non nul {} : {} -Vérifiez que votre installation de latex est correcte et signalez un bogue si c'est le cas. +Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. @@ -813,10 +813,10 @@ Vérifiez que votre installation de latex est correcte et signalez un bogue si c Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - Une exception s'est produite lors de la création de la formule latex. + Une exception s'est produite lors de la création de la formule LaTeX. Le processus '{}' a mis trop de temps à se terminer : {} -Vérifiez que votre installation de latex est correcte et signalez un bogue si c'est le cas. +Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. @@ -1090,7 +1090,7 @@ Vérifiez que votre installation de latex est correcte et signalez un bogue si c disableLatex - Désactiver le rendu latex pour ce texte + Désactiver le rendu LaTeX pour ce texte From b45e105202f1c3a3fc96409e4416deff4916aaac Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 22 Apr 2022 15:14:52 +0200 Subject: [PATCH 007/436] Disabling LaTeX popup if LaTeX support is disabled. --- .gitignore | 2 ++ LogarithmPlotter/logarithmplotter.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1a8dac4..11ffff4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,10 @@ linux/flatpak/.flatpak-builder **/**.jsc **/**.pyc **/**.qm +**/**.log *.jsc *.qmlc +*.log .DS_Store **/.DS_Store **/__pycache__/ diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 70073ef..3a8051c 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -135,7 +135,9 @@ def run(): if platform == "darwin": macOSFileOpenHandler.init_graphics(engine.rootObjects()[0]) - latex.check_latex_install() + # Check for LaTeX installation if LaTeX support is enabled + if config.getSetting("enable_latex"): + latex.check_latex_install() # Check for updates if config.getSetting("check_for_updates"): From b496807576de239f2535881e5967c3f8018bba4b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 22 Apr 2022 15:28:02 +0200 Subject: [PATCH 008/436] Disabling LaTeX integration by default. --- LogarithmPlotter/util/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index ecaa214..4f7b20c 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -26,7 +26,7 @@ DEFAULT_SETTINGS = { "check_for_updates": True, "reset_redo_stack": True, "last_install_greet": "0", - "enable_latex": True + "enable_latex": False } # Create config directory From 6b2afd3a1b3e4ddd39c137ec0d065db9d115f6cd Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 22 Apr 2022 16:25:20 +0200 Subject: [PATCH 009/436] Fixing generation script MacOS link. --- linux/generate-appstream-changelog.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/generate-appstream-changelog.sh b/linux/generate-appstream-changelog.sh index 9728103..1baeaa3 100644 --- a/linux/generate-appstream-changelog.sh +++ b/linux/generate-appstream-changelog.sh @@ -14,7 +14,7 @@ BEGIN { print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" @@ -59,7 +59,7 @@ BEGIN { print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" From 871630ef0b7d8fdb97344a340733bfcd3d050931 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 22 Apr 2022 16:32:56 +0200 Subject: [PATCH 010/436] Last fix for appstream generation script. --- linux/generate-appstream-changelog.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linux/generate-appstream-changelog.sh b/linux/generate-appstream-changelog.sh index 1baeaa3..331239f 100644 --- a/linux/generate-appstream-changelog.sh +++ b/linux/generate-appstream-changelog.sh @@ -48,6 +48,8 @@ BEGIN { text = substr(s,2) # Removing links text = gensub(/\[([^\]]+)\]\(([^\)]+)\)/, "\\1", "g", text); + # Fixing & in text. + text = gensub(/&/, "&", "g", text) print "
  • "text"
  • " } /^\s*--/ { @@ -75,7 +77,7 @@ END { print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print "
    " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" From 22c9151e0cffac36c8d570f69c1f8537a6391be9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 22 Apr 2022 16:53:48 +0200 Subject: [PATCH 011/436] Adding changelog for v0.2.0 --- CHANGELOG.md | 39 ++++++++++ linux/debian/changelog | 32 +++++++- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 77 ++++++++++++++++--- 3 files changed, 134 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e37d6..28fdd0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ # Changelog +## v0.2.0 (22 Apr 2022) + +**New** + + * (EXPERIMENTAL) LogarithmPlotter now has an optional LaTeX integration. + * It requires a LaTeX installation, including `latexmk` and `dvipng` available in the PATH. + * NOTE: LaTeX support is disabled by default and is only for working for the rendering on the graph. + * NOTE: The objects and history tab still use the legacy text based expression rendering. + * Thanks and contributions dialog, showing included libraries and translations, their license and author(s). + * LaTeX rendering can be disabled for texts, even if LaTeX is enabled. + +**Changes** + + * History re/undos only redraw the graph every 4 change at most in order to speed up the process when re/undoing a lot of changes. + * Gradients are no longer hidden when filtered out in the history tab. + +**Added translations** + + * LaTeX options and error messages + * Thanks and contribution dialog + * New option for text. + * Fixed translation of "repartition" which should be "distribution" in certain remaining strings. + +**Fixed bugs** + + * (macos) #1 - Opening files don't work on compiled versions of LogarithmPlotter on MacOS + * (snapcraft) Fixed bug preventing from launching LogarithmPlotter. This fix has been backported to v0.1.8. + * (snapcraft) Files are now properly opened. + * (snapcraft) Added changelog support. + +**Internal changes** + + * Moved python modules to "util" directory for more clarity. + * Moved flatpak metainfo to eu.ad5001.LogarithmPlotter repository. + * Componented the Mathlib library in order to have a more readable source. + * Added documentation for most internal JavaScript modules. + * Merge label drawing methods due to it's complexity. + * (flatpak) Updated SDK version to v5.15-21.08. + ## v0.1.8 (19 Feb 2022) **New** diff --git a/linux/debian/changelog b/linux/debian/changelog index 165844f..919e2aa 100644 --- a/linux/debian/changelog +++ b/linux/debian/changelog @@ -1,4 +1,30 @@ -logarithmplotter (0.1.8) stable; urgency=medium +logarithmplotter (0.2.0) stable; urgency=medium + + * New: (EXPERIMENTAL) LogarithmPlotter now has an optional LaTeX integration. + * It requires a LaTeX installation, including `latexmk` and `dvipng` available in the PATH. + * NOTE: LaTeX support is disabled by default and is only for working for the rendering on the graph. + * NOTE: The objects and history tab still use the legacy text based expression rendering. + * New: Thanks and contributions dialog, showing included libraries and translations, their license and author(s). + * New: LaTeX rendering can be disabled for texts, even if LaTeX is enabled. + * Changed: History re/undos only redraw the graph every 4 change at most in order to speed up the process when re/undoing a lot of changes. + * Changed: Gradients are no longer hidden when filtered out in the history tab. + * Added translation: LaTeX options and error messages + * Added translation: Thanks and contribution dialog + * Added translation: New option for text. + * Fixed translation: "repartition" which should be "distribution" in certain remaining strings. + * Fixed bug: (macos) #1 - Opening files don't work on compiled versions of LogarithmPlotter on MacOS + * Fixed bug: (snapcraft) Fixed bug preventing from launching LogarithmPlotter. This fix has been backported to v0.1.8. + * Fixed bug: (snapcraft) Files are now properly opened. + * Fixed bug: (snapcraft) Added changelog support. + * Internal changes: Moved python modules to "util" directory for more clarity. + * Internal changes: Moved flatpak metainfo to eu.ad5001.LogarithmPlotter repository. + * Internal changes: Componented the Mathlib library in order to have a more readable source. + * Internal changes: Added documentation for most internal JavaScript modules. + * Internal changes: (flatpak) Updated SDK version to v5.15-21.08. + + -- Ad5001 Fri, 22 Apr 2022 20:00:00 +0100 + + logarithmplotter (0.1.8) stable; urgency=medium * New: There is now a user manual for LogarithmPlotter! Contributions apprecriated. * Changed: A link to LogarithmPlotter's official website (https://apps.ad5001.eu/logarithmplotter/) has been added in the about dialog. @@ -16,7 +42,7 @@ logarithmplotter (0.1.8) stable; urgency=medium * Internal changes: Sidebar button width is now fixed. * Internal changes: Artifacts have been added to appstream metadata. - -- Ad5001 Sat, 19 Jan 2022 20:00:00 +0100 + -- Ad5001 Sat, 19 Feb 2022 20:00:00 +0100 logarithmplotter (0.1.7) stable; urgency=medium @@ -46,7 +72,7 @@ logarithmplotter (0.1.7) stable; urgency=medium * Internal changes: Trying to switch metainfo once more to try and fix another bug. * Internal changes: Keywords added to metainfo. - -- Ad5001 Thu, 03 Jan 2022 00:00:00 +0100 + -- Ad5001 Thu, 03 Feb 2022 00:00:00 +0100 logarithmplotter (0.1.6) stable; urgency=medium diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index ece209f..29b51d1 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -115,6 +115,59 @@ + + +

    Changes for v0.2.0:

    +

    New

    +
      +
    • (EXPERIMENTAL) LogarithmPlotter now has an optional LaTeX integration.
    • +
    • It requires a LaTeX installation, including `latexmk` and `dvipng` available in the PATH.
    • +
    • NOTE: LaTeX support is disabled by default and is only for working for the rendering on the graph.
    • +
    • NOTE: The objects and history tab still use the legacy text based expression rendering.
    • +
    • Thanks and contributions dialog, showing included libraries and translations, their license and author(s).
    • +
    • LaTeX rendering can be disabled for texts, even if LaTeX is enabled.
    • +
    +

    Changes

    +
      +
    • History re/undos only redraw the graph every 4 change at most in order to speed up the process when re/undoing a lot of changes.
    • +
    • Gradients are no longer hidden when filtered out in the history tab.
    • +
    +

    Added translations

    +
      +
    • LaTeX options and error messages
    • +
    • Thanks and contribution dialog
    • +
    • New option for text.
    • +
    • Fixed translation of "repartition" which should be "distribution" in certain remaining strings.
    • +
    +

    Fixed bugs

    +
      +
    • (macos) #1 - Opening files don't work on compiled versions of LogarithmPlotter on MacOS
    • +
    • (snapcraft) Fixed bug preventing from launching LogarithmPlotter. This fix has been backported to v0.1.8.
    • +
    • (snapcraft) Files are now properly opened.
    • +
    • (snapcraft) Added changelog support.
    • +
    +

    Internal changes

    +
      +
    • Moved python modules to "util" directory for more clarity.
    • +
    • Moved flatpak metainfo to eu.ad5001.LogarithmPlotter repository.
    • +
    • Componented the Mathlib library in order to have a more readable source.
    • +
    • Added documentation for most internal JavaScript modules.
    • +
    • Merge label drawing methods due to it's complexity.
    • +
    • (flatpak) Updated SDK version to v5.15-21.08.
    • +
    +
    + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-v0.2.0-setup.exe + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/LogarithmPlotter-v0.2.0-setup.dmg + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-0.2.0.tar.gz + + +

    Changes for v0.1.8:

    @@ -153,7 +206,7 @@ https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-v0.1.8-setup.exe
    - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-v0.1.8-setup.exe + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/LogarithmPlotter-v0.1.8-setup.dmg https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-0.1.8.tar.gz @@ -209,7 +262,7 @@ https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-v0.1.7-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-v0.1.7-setup.exe + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/LogarithmPlotter-v0.1.7-setup.dmg https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-0.1.7.tar.gz @@ -250,7 +303,7 @@ https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/logarithmplotter-v0.1.6-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/logarithmplotter-v0.1.6-setup.exe + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6-setup.dmg https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6.tar.gz @@ -280,7 +333,7 @@ https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/logarithmplotter-v0.1.5-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/logarithmplotter-v0.1.5-setup.exe + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5-setup.dmg https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5.tar.gz @@ -311,7 +364,7 @@ https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/logarithmplotter-v0.1.4-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/logarithmplotter-v0.1.4-setup.exe + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4-setup.dmg https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4.tar.gz @@ -332,7 +385,7 @@ https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/logarithmplotter-v0.1.3-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/logarithmplotter-v0.1.3-setup.exe + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3-setup.dmg https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3.tar.gz @@ -356,7 +409,7 @@ https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/logarithmplotter-v0.1.2-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/logarithmplotter-v0.1.2-setup.exe + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2-setup.dmg https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2.tar.gz @@ -364,10 +417,12 @@ -

    Changes for v0.1:

    -
      -
    • Initial release.
    • -
    + +

    Changes for v0.1:

    +
      +
    • Initial release.
    • +
    +
    From cb733a556cae1751920d03c480627b44e3833ac7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 22 Apr 2022 17:05:15 +0200 Subject: [PATCH 012/436] Releasing v0.2.0 --- LogarithmPlotter/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 69c5368..8fdcdde 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -18,7 +18,7 @@ from shutil import which __VERSION__ = "0.2.0" -is_release = False +is_release = True # Check if development version, if so get the date of the latest git patch From cf3e775834fb364adeddae36ef57f4eb23217369 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 23 Apr 2022 01:40:47 +0200 Subject: [PATCH 013/436] Fixing LaTeX disabling for texts not being saved. --- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index a46e840..0224089 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -83,7 +83,7 @@ class Text extends Common.DrawableObject { } export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.text] + return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.text, this.disableLatex] } getLabel() { From a5ce17e7f3c2ef34d9335844c27821d976ea5b2e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 23 Apr 2022 02:14:26 +0200 Subject: [PATCH 014/436] Updating appstream images --- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 29b51d1..3def02f 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -85,15 +85,15 @@ https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/ https://hosted.weblate.org/engage/logarithmplotter/ - https://apps.ad5001.eu/img/full/logarithmplotter.png - https://apps.ad5001.eu/img/en/logarithmplotter/phase.png - https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png - https://apps.ad5001.eu/img/de/gain.png - https://apps.ad5001.eu/img/de/logarithmplotter/phase.png - https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png - https://apps.ad5001.eu/img/fr/gain.png - https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png - https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png + https://apps.ad5001.eu/img/full/logarithmplotter.png?v=0.2 + https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.2 + https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.2 + https://apps.ad5001.eu/img/de/gain.png?v=0.2 + https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.2 + https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.2 + https://apps.ad5001.eu/img/fr/gain.png?v=0.2 + https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.2 + https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.2 https://apps.ad5001.eu/img/hu/gain.png https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png From 20f8d68f13f5defa5db4eba5c31438ac45bd949b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 23 Apr 2022 02:17:34 +0200 Subject: [PATCH 015/436] Starting v0.2.1 --- LogarithmPlotter/__init__.py | 4 ++-- linux/debian/control | 2 +- scripts/package-macosx.sh | 2 +- snapcraft.yaml | 2 +- win/installer.nsi | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 8fdcdde..d7eb5e9 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,8 +17,8 @@ """ from shutil import which -__VERSION__ = "0.2.0" -is_release = True +__VERSION__ = "0.2.1" +is_release = False # Check if development version, if so get the date of the latest git patch diff --git a/linux/debian/control b/linux/debian/control index 1f05813..76f50da 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -1,6 +1,6 @@ Package: logarithmplotter Source: logarithmplotter -Version: 0.2.0 +Version: 0.2.1 Architecture: all Maintainer: Ad5001 Depends: python3, python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), texlive-latex-base, dvipng diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index 070a164..60933a0 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -VERSION=0.2.0 +VERSION=0.2.1 title="LogarithmPlotter v${VERSION} Setup" finalDMGName="LogarithmPlotter-v${VERSION}-setup.dmg" applicationName=LogarithmPlotter diff --git a/snapcraft.yaml b/snapcraft.yaml index 9124698..7556df6 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,6 +1,6 @@ name: logarithmplotter title: LogarithmPlotter -version: '0.2.0' +version: '0.2.1' summary: 2D logarithmic-scaled plotter software to create asymptotic Bode plots confinement: strict base: core20 diff --git a/win/installer.nsi b/win/installer.nsi index 1d2c260..cb5cd41 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -11,7 +11,7 @@ Unicode True !define PROG_ID "LogarithmPlotter.File.1" !define DEV_NAME "Ad5001" !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" -!define VERSION_SHORT "0.2.0" +!define VERSION_SHORT "0.2.1" !define APP_VERSION "${VERSION_SHORT}.0" !define COPYRIGHT "Ad5001 (c) 2022" !define DESCRIPTION "Create graphs with logarithm scales." From 876ea1eaa862d95b62c4ac5136144a2e02022aae Mon Sep 17 00:00:00 2001 From: ovari Date: Sun, 1 May 2022 01:26:39 +0000 Subject: [PATCH 016/436] Translated using Weblate (Hungarian) Currently translated at 100.0% (205 of 205 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 85 +++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index d49c7ac..5d07339 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -27,7 +27,7 @@ Official website - + Hivatalos honlap
    @@ -100,7 +100,7 @@ Enable LaTeX rendering - + LaTeX-megjelenítés engedélyezése @@ -120,7 +120,7 @@ &User manual - + &Használati utasítás @@ -135,7 +135,7 @@ &Thanks - + &Köszönjük @@ -250,12 +250,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Enable LaTeX rendering - + LaTeX-megjelenítés engedélyezése User manual - + Használati utasítás @@ -273,7 +273,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Filter... - + Szűrő… @@ -524,27 +524,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Thanks and Contributions - LogarithmPlotter - + Köszönet és hozzájárulás - LogarithmPlotter Source code - + Forráskód Original library by Raphael Graf - + Eredeti könyvtár: Graf Raphael Source - + Forrás Ported to Javascript by Matthew Crumley - + JavaScript-átalakítás: Crumley Máté @@ -553,63 +553,63 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Website - + Honlap Ported to QMLJS by Ad5001 - + QMLJS-átalakítás: Ad5001 Libraries included - + Tartalmazott könyvtárak Email - + E-mail English - + angol French - + francia German - + német Hungarian - + magyar Github - + GitHub Norwegian - + norvég Translations included - + A felhasználói felület nyelvei Improve - + Fejlesztés @@ -631,7 +631,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. %1 %2's color changed from %3 to %4. - + %1 %2 színe %3-ról %4-re változott. @@ -659,7 +659,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. If you have latex enabled, you can use use latex markup in between $$ to create equations. - + Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -679,7 +679,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. @@ -688,7 +688,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. @@ -696,12 +696,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 of %2 changed from %3 to %4. - + %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -772,12 +772,14 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + Nem található LaTeX telepítés. +Ha már telepítve van egy LaTeX disztribúció, győződjön meg arról, hogy az telepítve van az elérési útján. +Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https://tug.org/texlive/ címről. DVIPNG was not found. Make sure you include it from your Latex distribution. - + DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. @@ -786,7 +788,11 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + Kivétel történt a LaTeX-képlet létrehozása során. +A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződött: + +{} +Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. @@ -794,7 +800,10 @@ Please make sure your latex installation is correct and report a bug if so. - + Kivétel történt a LaTeX-képlet létrehozása során. +A(z) „{}” folyamat túl sokáig tartott a befejezéshez: +{} +Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. @@ -803,7 +812,7 @@ Please make sure your latex installation is correct and report a bug if so. %1 %2 renamed to %3. - + %1 %2 átnevezve erre: %3. @@ -1068,7 +1077,7 @@ Please make sure your latex installation is correct and report a bug if so. disableLatex - + LaTeX-megjelenítés letiltása ennél a szövegnél @@ -1192,13 +1201,13 @@ Please make sure your latex installation is correct and report a bug if so. %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. From ef04b2aa58f6bb0c5ececeab056af678ab588f81 Mon Sep 17 00:00:00 2001 From: Sergio Varela Date: Tue, 10 May 2022 12:24:31 +0000 Subject: [PATCH 017/436] Translated using Weblate (Spanish) Currently translated at 13.6% (28 of 205 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index d0e5cad..b8d06f2 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -90,62 +90,62 @@ Check for updates on startup - + Comprobación de las actualizaciones al arrancar Reset redo stack automaticly - + Restablecer la pila de rehacer automáticamente Enable LaTeX rendering - + Activar el renderizado de LaTeX &Help - + &Ayuda &Source code - + &Código fuente &Report a bug - + &Informar de un error &User manual - + &Manual del usuario &Changelog - + &Registro de cambios &Help translating! - + &¡Ayuda a la traducción! &Thanks - + &Agradecimientos &About - + &Acerca de Save unsaved changes? - + ¿Guardar los cambios no guardados? From 2d46de35d29ca7a0a997bcdaa7cc84f97df5c0c4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 15 May 2022 00:28:11 +0200 Subject: [PATCH 018/436] Fixing snap --- snapcraft.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index 9124698..4224b51 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -80,8 +80,8 @@ parts: stage-packages: - breeze-icon-theme # Latex dependencies - - texlive-latex-base - - dvipng + #- texlive-latex-base Causes symlink issues and being rejected by the Snap store. + #- dvipng # Additional dependencies - libxcomposite1 - libxcursor1 @@ -149,7 +149,7 @@ parts: source: . plugin: dump organize: - CHANGELOG.md: lib/python3.8/site-packages/LogarithmPlotter/CHANGELOG.md + CHANGELOG.md: lib/python3.8/site-packages/LogarithmPlotter/util/ apps: logarithmplotter: From fad5325501ccd898762970119738b2cb99517333 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 17 Oct 2022 20:25:29 +0200 Subject: [PATCH 019/436] Better handling of Object names in a separate dictionary. --- .../LogarithmPlotter/LogarithmPlotter.qml | 1 + .../ObjectLists/EditorDialog.qml | 34 +++++++---- .../ObjectLists/ObjectLists.qml | 3 +- .../LogarithmPlotter/PickLocationOverlay.qml | 4 +- .../LogarithmPlotter/js/history/create.js | 8 ++- .../js/history/editproperty.js | 8 +-- .../LogarithmPlotter/js/history/name.js | 8 ++- .../eu/ad5001/LogarithmPlotter/js/objects.js | 58 ++++++++++++------- .../ad5001/LogarithmPlotter/js/objs/common.js | 2 +- .../LogarithmPlotter/js/objs/gainbode.js | 2 +- .../LogarithmPlotter/js/objs/phasebode.js | 2 +- .../LogarithmPlotter/js/objs/xcursor.js | 2 +- LogarithmPlotter/util/helper.py | 1 + 13 files changed, 84 insertions(+), 49 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 3a53be3..9b69b47 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -255,6 +255,7 @@ ApplicationWindow { for(var objData of data['objects'][objType]) { var obj = new Objects.types[objType](...objData) Objects.currentObjects[objType].push(obj) + Objects.currentObjectsByName[obj.name] = obj } } else { error += qsTr("Unknown object type: %1.").arg(objType) + "\n"; diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/EditorDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/EditorDialog.qml index e4721ed..9cf4a12 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/EditorDialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/EditorDialog.qml @@ -73,27 +73,37 @@ D.Dialog { anchors.top: dlgTitle.bottom width: objEditor.width - 20 spacing: 10 + + D.MessageDialog { + id: invalidNameDialog + title: qsTr("LogarithmPlotter - Invalid object name") + text: "" + function showDialog(objectName) { + text = qsTr("An object with the name '%1' already exists.").arg(objectName) + open() + } + } Setting.TextSetting { id: nameProperty height: 30 label: qsTr("Name") icon: "common/label.svg" - min: 1 width: dlgProperties.width value: objEditor.obj.name onChanged: function(newValue) { - var newName = Utils.parseName(newValue) + let newName = Utils.parseName(newValue) if(newName != '' && objEditor.obj.name != newName) { - if(Objects.getObjectByName(newName) != null) { - newName = ObjectsCommons.getNewName(newName) + if(newName in Objects.currentObjectsByName) { + invalidNameDialog.showDialog(newName) + } else { + history.addToHistory(new HistoryLib.NameChanged( + objEditor.obj.name, objEditor.objType, newName + )) + Objects.renameObject(obj.name, newName) + objEditor.obj = Objects.currentObjects[objEditor.objType][objEditor.objIndex] + objectListList.update() } - history.addToHistory(new HistoryLib.NameChanged( - objEditor.obj.name, objEditor.objType, newName - )) - Objects.currentObjects[objEditor.objType][objEditor.objIndex].name = newName - objEditor.obj = Objects.currentObjects[objEditor.objType][objEditor.objIndex] - objectListList.update() } } } @@ -213,7 +223,7 @@ D.Dialog { []) : modelData[1].values) : [] - // Translated verison of the model. + // Translated version of the model. model: selectObjMode ? baseModel : modelData[1].translatedValues visible: paramTypeIn(modelData[1], ['ObjectType', 'Enum']) currentIndex: baseModel.indexOf(selectObjMode ? objEditor.obj[modelData[0]].name : objEditor.obj[modelData[0]]) @@ -222,7 +232,7 @@ D.Dialog { if(selectObjMode) { // This is only done when what we're selecting are Objects. // Setting object property. - var selectedObj = Objects.getObjectByName(baseModel[newIndex], modelData[1].objType) + var selectedObj = Objects.currentObjectsByName[baseModel[newIndex]] if(newIndex != 0) { // Make sure we don't set the object to null. if(selectedObj == null) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index d19ddaa..945c200 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -193,8 +193,7 @@ ScrollView { history.addToHistory(new HistoryLib.DeleteObject( obj.name, objType, obj.export() )) - Objects.currentObjects[objType][index].delete() - Objects.currentObjects[objType].splice(index, 1) + Objects.deleteObject(obj.name) objectListList.update() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 6c4ddec..8ef80d6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -98,7 +98,7 @@ Item { 'Expression': () => new MathLib.Expression(newValue), 'number': () => parseFloat(newValue) }[Objects.types[objType].properties()[propertyX]]() - let obj = Objects.getObjectByName(objName, objType) + let obj = Objects.currentObjectsByName[objName] // getObjectByName(objName, objType) history.addToHistory(new HistoryLib.EditedProperty( objName, objType, propertyX, obj[propertyX], newValue )) @@ -112,7 +112,7 @@ Item { 'Expression': () => new MathLib.Expression(newValue), 'number': () => parseFloat(newValue) }[Objects.types[objType].properties()[propertyY]]() - let obj = Objects.getObjectByName(objName, objType) + let obj = Objects.currentObjectsByName[objName] // Objects.getObjectByName(objName, objType) history.addToHistory(new HistoryLib.EditedProperty( objName, objType, propertyY, obj[propertyY], newValue )) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js index 2c3fe18..00af298 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js @@ -36,9 +36,11 @@ class CreateNewObject extends C.Action { undo() { - var targetIndex = Objects.getObjectsName(this.targetType).indexOf(this.targetName) - Objects.currentObjects[this.targetType][targetIndex].delete() - Objects.currentObjects[this.targetType].splice(targetIndex, 1) + Objects.deleteObject(this.targetName) + //let targetIndex = Objects.getObjectsName(this.targetType).indexOf(this.targetName) + //delete Objects.currentObjectsByName[this.targetName] + //Objects.currentObjects[this.targetType][targetIndex].delete() + //Objects.currentObjects[this.targetType].splice(targetIndex, 1) } redo() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js index 31c21df..140a54b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js @@ -49,19 +49,19 @@ class EditedProperty extends C.Action { this.newValue = MathLib.parseDomain(this.newValue); } else { // Objects - this.previousValue = Objects.getObjectByName(this.previousValue); - this.newValue = Objects.getObjectByName(this.newValue); + this.previousValue = Objects.currentObjectsByName[this.previousValue] // Objects.getObjectByName(this.previousValue); + this.newValue = Objects.currentObjectsByName[this.newValue] // Objects.getObjectByName(this.newValue); } } this.setReadableValues() } undo() { - Objects.getObjectByName(this.targetName, this.targetType)[this.targetProperty] = this.previousValue + Objects.currentObjectsByName[this.targetName][this.targetProperty] = this.previousValue } redo() { - Objects.getObjectByName(this.targetName, this.targetType)[this.targetProperty] = this.newValue + Objects.currentObjectsByName[this.targetName][this.targetProperty] = this.newValue } export() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js index 015895f..0ec790d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js @@ -40,11 +40,15 @@ class NameChanged extends EP.EditedProperty { } undo() { - Objects.getObjectByName(this.newValue, this.targetType)['name'] = this.previousValue + Objects.renameObject(this.newValue, this.previousValue) } redo() { - Objects.getObjectByName(this.previousValue, this.targetType)['name'] = this.newValue + Objects.renameObject(this.previousValue, this.newValue) + //let obj = Objects.currentObjectsByName[this.previousValue] + //obj.name = this.newValue + //Objects.currentObjectsByName[this.newValue] = obj + //delete Objects.currentObjectsByName[this.previousValue] } getReadableString() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js index e27562d..b2a5b15 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js @@ -25,30 +25,37 @@ var types = {} var currentObjects = {} +var currentObjectsByName = {} -function getObjectByName(objName, objType = null) { - var objectTypes = Object.keys(currentObjects) - if(typeof objType == 'string' && objType != "") { - if(objType == "ExecutableObject") { - objectTypes = getExecutableTypes() - } else if(currentObjects[objType] != undefined) { - objectTypes = [objType] - } - } - if(Array.isArray(objType)) objectTypes = objType - var retObj = null - if(objName != "" && objName != null) { - objectTypes.forEach(function(objType){ - if(currentObjects[objType] == undefined) return null - currentObjects[objType].forEach(function(obj){ - if(obj.name == objName) retObj = obj - }) - }) - } - return retObj +function renameObject(oldName, newName) { + /** + * Renames an object from its old name to the new one. + * @param {string} oldName - Current name of the object. + * @param {string} newName - Name to rename the object to. + */ + let obj = currentObjectsByName[oldName] + delete currentObjectsByName[oldName] + currentObjectsByName[newName] = obj + obj.name = newName +} + +function deleteObject(objName) { + /** + * Deletes an object by its given name. + * @param {string} objName - Current name of the object. + */ + let obj = currentObjectsByName[objName] + delete currentObjectsByName[objName] + currentObjects[obj.type].splice(currentObjects.indexOf(obj),1) + obj.delete() } function getObjectsName(objType) { + /** + * Gets a list of all names of a certain object type. + * @param {string} objType - Type of the object to query. Can be ExecutableObject for all ExecutableObjects. + * @return {array} List of names of the objects. + */ if(objType == "ExecutableObject") { var types = getExecutableTypes() var elementNames = [''] @@ -62,15 +69,26 @@ function getObjectsName(objType) { } function getExecutableTypes() { + /** + * Returns a list of all object types which are executable objects. + * @return {array} List of all object types which are executable objects. + */ return Object.keys(currentObjects).filter(objType => types[objType].executable()) } function createNewRegisteredObject(objType, args=[]) { + /** + * Creates and register an object in the database. + * @param {string} objType - Type of the object to create. + * @param {string} args - List of arguments for the objects (can be empty). + * @return {[objType]} Newly created object. + */ if(Object.keys(types).indexOf(objType) == -1) return null // Object type does not exist. var newobj = new types[objType](...args) if(Object.keys(currentObjects).indexOf(objType) == -1) { currentObjects[objType] = [] } currentObjects[objType].push(newobj) + currentObjectsByName[newobj.name] = newobj return newobj } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 3864b2f..7af97f7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -40,7 +40,7 @@ function getNewName(allowedLetters) { var num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) ret = letter + (num > 0 ? Utils.textsub(num-1) : '') newid += 1 - } while(Objects.getObjectByName(ret) != null) + } while(ret in Objects.currentObjectsByName) return ret } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index ff8236c..a95f53e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -49,7 +49,7 @@ class GainBode extends Common.ExecutableObject { this.type = 'Gain Bode' if(typeof om_0 == "string") { // Point name or create one - om_0 = Objects.getObjectByName(om_0, 'Point') + om_0 = Objects.currentObjectsByName[om_0] if(om_0 == null) { // Create new point om_0 = Objects.createNewRegisteredObject('Point') diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index e3d7be0..63b01a6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -48,7 +48,7 @@ class PhaseBode extends Common.ExecutableObject { this.phase = phase if(typeof om_0 == "string") { // Point name or create one - om_0 = Objects.getObjectByName(om_0, 'Point') + om_0 = Objects.currentObjectsByName[om_0] if(om_0 == null) { // Create new point om_0 = Objects.createNewRegisteredObject('Point') diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js index 52c989f..0199b6a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js @@ -56,7 +56,7 @@ class XCursor extends Common.DrawableObject { this.x = x this.targetElement = targetElement if(typeof targetElement == "string") { - this.targetElement = Objects.getObjectByName(targetElement, elementTypes) + this.targetElement = Objects.currentObjectsByName[targetElement] } this.labelPosition = labelPosition this.displayStyle = displayStyle diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index 4f2a7da..47e3992 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -149,6 +149,7 @@ class Helper(QObject): @Slot() def fetchChangelog(self): changelog_cache_path = path.join(path.dirname(path.realpath(__file__)), "CHANGELOG.md") + print(changelog_cache_path) if path.exists(changelog_cache_path): # We have a cached version of the changelog, for env that don't have access to the internet. f = open(changelog_cache_path); From 6b535dd8a256e412f453fc63111a5cc3dde1f40b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 17 Oct 2022 22:30:59 +0200 Subject: [PATCH 020/436] Adding object properties usable in expressions --- .../qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js | 6 +++++- .../eu/ad5001/LogarithmPlotter/js/math/common.js | 13 +++++++++---- .../ad5001/LogarithmPlotter/js/math/expression.js | 10 ++++++---- .../eu/ad5001/LogarithmPlotter/js/math/sequence.js | 9 +++++---- .../qml/eu/ad5001/LogarithmPlotter/js/objects.js | 7 ++++--- .../eu/ad5001/LogarithmPlotter/js/objs/common.js | 2 +- 6 files changed, 30 insertions(+), 17 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 9253edc..23b164f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -194,6 +194,7 @@ function evaluate(tokens, expr, values) { nstack.push(f(resolveExpression(n1, values), resolveExpression(n2, values), resolveExpression(n3, values))); } } else if (type === IVAR) { + // Check for variable value if (item.value in expr.functions) { nstack.push(expr.functions[item.value]); } else if (item.value in expr.unaryOps && expr.parser.isOperatorEnabled(item.value)) { @@ -219,8 +220,11 @@ function evaluate(tokens, expr, values) { f = nstack.pop(); if (f.apply && f.call) { nstack.push(f.apply(undefined, args)); + } else if(f.execute) { + // Objects & expressions execution + nstack.push(f.execute.apply(undefined, args)); } else { - throw new Error(f + ' is not a function'); + throw new Error(f + ' cannot be executed'); } } else if (type === IFUNDEF) { // Create closure to keep references to arguments and expression diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 4cadcf5..80f9402 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -22,7 +22,9 @@ .import "../utils.js" as Utils .import "latex.js" as Latex -var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manualy +const DERIVATION_PRECISION = 0.1 + +var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually "pi": Math.PI, "π": Math.PI, "inf": Infinity, @@ -33,18 +35,21 @@ var evalVariables = { // Variables not provided by expr-eval.js, needs to be pro } var currentVars = {} +var currentObjectsByName = {} // Mirror of currentObjectsByName in objects.js const parser = new ExprEval.Parser() + +parser.consts = Object.assign({}, parser.consts, evalVariables) + +// Function definition parser.functions.integral = function(a, b, f, variable) { // https://en.wikipedia.org/wiki/Simpson%27s_rule + // Simpler, faster than tokenizing the expression f = parser.parse(f).toJSFunction(variable, currentVars) return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) } -const DERIVATION_PRECISION = 0.1 - parser.functions.derivative = function(f, variable, x) { f = parser.parse(f).toJSFunction(variable, currentVars) return (f(x+DERIVATION_PRECISION/2)-f(x-DERIVATION_PRECISION/2))/DERIVATION_PRECISION } - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index 58c4528..6007a3b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -30,23 +30,25 @@ class Expression { this.expr = expr this.calc = C.parser.parse(expr).simplify() this.cached = this.isConstant() - this.cachedValue = this.cached ? this.calc.evaluate(C.evalVariables) : null + this.cachedValue = this.cached ? this.calc.evaluate(C.currentObjectsByName) : null this.latexMarkup = Latex.expression(this.calc.tokens) } isConstant() { - return !this.expr.includes("x") && !this.expr.includes("n") + let vars = this.calc.variables() + return !vars.includes("x") && !vars.includes("n") } execute(x = 1) { if(this.cached) return this.cachedValue - C.currentVars = Object.assign({'x': x}, C.evalVariables) + C.currentVars = Object.assign({'x': x}, C.currentObjectsByName) + //console.log("Executing", this.expr, "with", JSON.stringify(C.currentVars)) return this.calc.evaluate(C.currentVars) } simplify(x) { var expr = this.calc.substitute('x', x).simplify() - if(expr.evaluate(C.evalVariables) == 0) return '0' + if(expr.evaluate() == 0) return '0' var str = Utils.makeExpressionReadable(expr.toString()); if(str != undefined && str.match(/^\d*\.\d+$/)) { if(str.split('.')[1].split('0').length > 7) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index cdee74c..ddfe4e0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -39,7 +39,7 @@ class Sequence extends Expr.Expression { if(['string', 'number'].includes(typeof this.calcValues[n])) { let parsed = C.parser.parse(this.calcValues[n].toString()).simplify() this.latexValues[n] = Latex.expression(parsed.tokens) - this.calcValues[n] = parsed.evaluate(C.evalVariables) + this.calcValues[n] = parsed.evaluate() } this.valuePlus = parseInt(valuePlus) } @@ -65,9 +65,10 @@ class Sequence extends Expr.Expression { cache(n = 1) { var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) var expr = C.parser.parse(str).simplify() - var l = {'n': n-this.valuePlus} // Just in case, add n (for custom functions) - l[this.name] = this.calcValues - C.currentVars = Object.assign(l, C.evalVariables) + C.currentVars = Object.assign( + {'n': n-this.valuePlus, [this.name]: this.calcValues}, // Just in case, add n (for custom functions) + C.currentObjectsByName + ) this.calcValues[n] = expr.evaluate(C.currentVars) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js index b2a5b15..1a23f7c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js @@ -19,14 +19,15 @@ .pragma library .import "utils.js" as Utils -.import "mathlib.js" as MathLib +.import "math/common.js" as MathCommons .import "parameters.js" as P var types = {} var currentObjects = {} var currentObjectsByName = {} - +MathCommons.currentObjectsByName = currentObjectsByName // Required for using objects in variables. + function renameObject(oldName, newName) { /** * Renames an object from its old name to the new one. @@ -46,7 +47,7 @@ function deleteObject(objName) { */ let obj = currentObjectsByName[objName] delete currentObjectsByName[objName] - currentObjects[obj.type].splice(currentObjects.indexOf(obj),1) + currentObjects[obj.type].splice(currentObjects[obj.type].indexOf(obj),1) obj.delete() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 7af97f7..d8e8d45 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -187,7 +187,7 @@ class DrawableObject { * Callback method when one of the properties of the object is updated. */ update() { - for(var req of this.requiredBy) { + for(let req of this.requiredBy) { req.update() } } From 1ba594c4f7241bbb533c0225c9d6e35fcdc1619a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 17 Oct 2022 22:54:02 +0200 Subject: [PATCH 021/436] Fixing executing function in expression. --- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 23b164f..5056ed2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -222,7 +222,7 @@ function evaluate(tokens, expr, values) { nstack.push(f.apply(undefined, args)); } else if(f.execute) { // Objects & expressions execution - nstack.push(f.execute.apply(undefined, args)); + nstack.push(f.execute.apply(f, args)); } else { throw new Error(f + ' cannot be executed'); } From 1a433eba27f3105023bbae139a0cd240aa94e21a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 00:45:53 +0200 Subject: [PATCH 022/436] Propagated property updates to dependent objects. + Fixing object expression dependency at setup. + Fixing function calls in utils + Removing some unnecessary comments --- .../LogarithmPlotter/LogarithmPlotter.qml | 11 ++++-- .../js/history/editproperty.js | 2 + .../LogarithmPlotter/js/math/expression.js | 23 ++++++++++-- .../ad5001/LogarithmPlotter/js/objs/common.js | 37 ++++++++++++++++--- .../LogarithmPlotter/js/objs/repartition.js | 8 ---- .../js/objs/sommephasesbode.js | 4 -- .../ad5001/LogarithmPlotter/js/objs/text.js | 6 --- .../eu/ad5001/LogarithmPlotter/js/utils.js | 14 +++---- 8 files changed, 68 insertions(+), 37 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 9b69b47..ca1b087 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -249,11 +249,12 @@ ApplicationWindow { // Importing objects Objects.currentObjects = {} - for(var objType in data['objects']) { + Objects.currentObjectsByName = {} + for(let objType in data['objects']) { if(Object.keys(Objects.types).indexOf(objType) > -1) { Objects.currentObjects[objType] = [] - for(var objData of data['objects'][objType]) { - var obj = new Objects.types[objType](...objData) + for(let objData of data['objects'][objType]) { + let obj = new Objects.types[objType](...objData) Objects.currentObjects[objType].push(obj) Objects.currentObjectsByName[obj.name] = obj } @@ -262,6 +263,10 @@ ApplicationWindow { } } + // Updating object dependencies. + for(let objName in Objects.currentObjectsByName) + Objects.currentObjectsByName[objName].update() + // Importing history if("history" in data) history.unserialize(...data["history"]) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js index 140a54b..87be759 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js @@ -58,10 +58,12 @@ class EditedProperty extends C.Action { undo() { Objects.currentObjectsByName[this.targetName][this.targetProperty] = this.previousValue + Objects.currentObjectsByName[this.targetName].update() } redo() { Objects.currentObjectsByName[this.targetName][this.targetProperty] = this.newValue + Objects.currentObjectsByName[this.targetName].update() } export() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index 6007a3b..88ebac6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -30,7 +30,7 @@ class Expression { this.expr = expr this.calc = C.parser.parse(expr).simplify() this.cached = this.isConstant() - this.cachedValue = this.cached ? this.calc.evaluate(C.currentObjectsByName) : null + this.cachedValue = this.cached && this.allRequirementsFullfilled() ? this.calc.evaluate(C.currentObjectsByName) : null this.latexMarkup = Latex.expression(this.calc.tokens) } @@ -39,8 +39,25 @@ class Expression { return !vars.includes("x") && !vars.includes("n") } + requiredObjects() { + return this.calc.variables().filter(objName => objName != "x" && objName != "n") + } + + allRequirementsFullfilled() { + return this.requiredObjects().every(objName => objName in C.currentObjectsByName) + } + + recache() { + if(this.cached) + this.cachedValue = this.calc.evaluate(C.currentObjectsByName) + } + execute(x = 1) { - if(this.cached) return this.cachedValue + if(this.cached) { + if(this.cachedValue == null) + this.cachedValue = this.calc.evaluate(C.currentObjectsByName) + return this.cachedValue + } C.currentVars = Object.assign({'x': x}, C.currentObjectsByName) //console.log("Executing", this.expr, "with", JSON.stringify(C.currentVars)) return this.calc.evaluate(C.currentVars) @@ -68,7 +85,7 @@ class Expression { } toString(forceSign=false) { - var str = Utils.makeExpressionReadable(this.calc.toString()) + let str = Utils.makeExpressionReadable(this.calc.toString()) if(str[0] != '-' && forceSign) str = '+' + str return str } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index d8e8d45..e37ad75 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -21,6 +21,8 @@ .import "../utils.js" as Utils .import "../objects.js" as Objects .import "../math/latex.js" as Latex +.import "../parameters.js" as P +.import "../math/common.js" as C // This file contains the default data to be imported from all other objects @@ -116,6 +118,7 @@ class DrawableObject { this.color = color this.labelContent = labelContent // "null", "name", "name + value" this.requiredBy = [] + this.requires = [] } /** @@ -187,18 +190,40 @@ class DrawableObject { * Callback method when one of the properties of the object is updated. */ update() { - for(let req of this.requiredBy) { + // Refreshing dependencies. + for(let obj of this.requires) + obj.requiredBy = obj.requiredBy.filter(dep => dep != this) + // Checking objects this one depends on + this.requires = [] + let properties = this.constructor.properties() + for(let property in properties) + if(properties[property] == 'Expression' && this[property] != null) { + // Expressions with dependencies + for(let objName of this[property].requiredObjects()) { + this.requires.push(C.currentObjectsByName[objName]) + C.currentObjectsByName[objName].requiredBy.push(this) + } + if(this[property].cached && this[property].requiredObjects().length > 0) + // Recalculate + this[property].recache() + + } else if(typeof properties[property] == 'object' && 'type' in properties[property] && properties[property] == 'ObjectType' && this[property] != null) { + // Object dependency + this.requires.push(this[property]) + this[property].requiredBy.push(this) + } + + // Updating objects dependent on this one + for(let req of this.requiredBy) req.update() - } } /** * Callback method when the object is about to get deleted. */ delete() { - for(var toRemove of this.requiredBy) { - toRemove.delete() - Objects.currentObjects[toRemove.type] = Objects.currentObjects[toRemove.type].filter(obj => obj.name != toRemove.name) + for(let toRemove of this.requiredBy) { + Objects.deleteObject(toRemove.name) } } @@ -261,7 +286,7 @@ class DrawableObject { } /** - * Automaticly draw text (by default the label of the object on the \c canvas with + * Automatically draw text (by default the label of the object on the \c canvas with * the 2D context \c ctx depending on user settings. * This method takes into account both the \c posX and \c posY of where the label * should be displayed, including the \c labelPosition relative to it. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js index da8c4e1..0f25c4c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js @@ -27,14 +27,6 @@ class RepartitionFunction extends Common.ExecutableObject { static type(){return 'Repartition'} static displayType(){return qsTr('Repartition')} static displayTypeMultiple(){return qsTr('Repartition functions')} - /*static properties() {return { - 'beginIncluded': 'boolean', - 'drawLineEnds': 'boolean', - 'comment1': 'Note: Specify the properties for each potential result.', - 'probabilities': new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d\.,]+$/, 'P({name} = ', ') = '), - 'labelPosition': new P.Enum('above', 'below', 'left', 'right', 'above-left', 'above-right', 'below-left', 'below-right'), - 'labelX': 'number' - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js index bfa6c4b..5d3f0da 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js @@ -30,10 +30,6 @@ class SommePhasesBode extends Common.ExecutableObject { static displayType(){return qsTr('Bode Phases Sum')} static displayTypeMultiple(){return qsTr('Bode Phases Sum')} static createable() {return false} - /*static properties() {return { - 'labelPosition': new P.Enum('above', 'below', 'left', 'right', 'above-left', 'above-right', 'below-left', 'below-right'), - 'labelX': 'number' - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index 0224089..77f5c5d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -29,12 +29,6 @@ class Text extends Common.DrawableObject { static type(){return 'Text'} static displayType(){return qsTr('Text')} static displayTypeMultiple(){return qsTr('Texts')} - /*static properties() {return { - 'x': 'Expression', - 'y': 'Expression', - 'labelPosition': new P.Enum('center', 'above', 'below', 'left', 'right', 'above-left', 'above-right', 'below-left', 'below-right'), - 'text': 'string', - }}*/ static properties() {return { [QT_TRANSLATE_NOOP('prop','x')]: 'Expression', [QT_TRANSLATE_NOOP('prop','y')]: 'Expression', diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index 017b411..a383846 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -129,11 +129,11 @@ function simplifyExpression(str) { var replacements = [ // Operations not done by parser. [// Decomposition way 2 - /(^.?|[+-] |\()([-.\d\w]+) ([*/]) \((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\)(.?$| [+-]|\))/g, + /(^|[+-] |\()([-.\d\w]+) ([*/]) \((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\)($| [+-]|\))/g, "$1$2 $3 $4 $6 $2 $3 $7$9" ], [ // Decomposition way 2 - /(^.?|[+-] |\()\((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\) ([*/]) ([-.\d\w]+)(.?$| [+-]|\))/g, + /(^|[+-] |\()\((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\) ([*/]) ([-.\d\w]+)($| [+-]|\))/g, "$1$2 $7 $8 $4 $5 $7 $8$9" ], [ // Factorisation of π elements. @@ -159,19 +159,19 @@ function simplifyExpression(str) { } ], [ // Removing parenthesis when content is only added from both sides. - /(^.?|[+-] |\()\(([^)(]+)\)(.?$| [+-]|\))/g, + /(^|[+-] |\()\(([^)(]+)\)($| [+-]|\))/g, function(match, b4, middle, after) {return `${b4}${middle}${after}`} ], [ // Removing parenthesis when content is only multiplied. - /(^.?|[*\/] |\()\(([^)(+-]+)\)(.?$| [*\/+-]|\))/g, + /(^|[*\/] |\()\(([^)(+-]+)\)($| [*\/+-]|\))/g, function(match, b4, middle, after) {return `${b4}${middle}${after}`} ], [ // Removing parenthesis when content is only multiplied. - /(^.?|[*\/-+] |\()\(([^)(+-]+)\)(.?$| [*\/]|\))/g, + /(^|[*\/-+] |\()\(([^)(+-]+)\)($| [*\/]|\))/g, function(match, b4, middle, after) {return `${b4}${middle}${after}`} ], [// Simplification additions/substractions. - /(^.?|[^*\/] |\()([-.\d]+) (\+|\-) (\([^)(]+\)|[^)(]+) (\+|\-) ([-.\d]+)(.?$| [^*\/]|\))/g, + /(^|[^*\/] |\()([-.\d]+) (\+|\-) (\([^)(]+\)|[^)(]+) (\+|\-) ([-.\d]+)($| [^*\/]|\))/g, function(match, b4, n1, op1, middle, op2, n2, after) { var total if(op2 == '+') { @@ -258,7 +258,7 @@ function makeExpressionReadable(str) { [/\[([^\[\]]+)\]/g, function(match, p1) { return textsub(p1) }], [/(\d|\))×/g, '$1'], //[/×(\d|\()/g, '$1'], - [/\(([^)(+.\/-]+)\)/g, "$1"], + [/[^a-z]\(([^)(+.\/-]+)\)/g, "$1"], [/integral\((.+),\s?(.+),\s?("|')(.+)("|'),\s?("|')(.+)("|')\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { if(a.length < b.length) { return `∫${textsub(a)}${textsup(b)} ${body} d${by}` From 8c6784663ea66b29e339c416d45968415293ee15 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 00:47:27 +0200 Subject: [PATCH 023/436] Fixing build --- ci/drone.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/drone.yml b/ci/drone.yml index d699291..487b0f5 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,6 +14,7 @@ steps: - name: Linux test image: ad5001/ubuntu-pyside2-xvfb:hirsute-5.15.2 commands: + - apt update - apt install -y texlive-latex-base dvipng - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf From b8d312bb23bb3b90b324c91ac609d2ec2aef6618 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 00:49:15 +0200 Subject: [PATCH 024/436] =?UTF-8?q?Fixing=20build=C2=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ci/drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 487b0f5..249cbc3 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -14,8 +14,8 @@ steps: - name: Linux test image: ad5001/ubuntu-pyside2-xvfb:hirsute-5.15.2 commands: - - apt update - - apt install -y texlive-latex-base dvipng + #- apt update + #- apt install -y texlive-latex-base dvipng - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf From dfdd576296228776769f7ba25bfeecaf54c8c55d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 01:12:24 +0200 Subject: [PATCH 025/436] Componentizing the object's row. --- .../ObjectLists/ObjectLists.qml | 147 +------------- .../ObjectLists/ObjectRow.qml | 180 ++++++++++++++++++ .../LogarithmPlotter/ObjectLists/qmldir | 2 +- .../js/history/editproperty.js | 2 +- 4 files changed, 191 insertions(+), 140 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 945c200..cb68524 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -21,14 +21,13 @@ import QtQuick.Dialogs 1.3 as D import QtQuick.Controls 2.12 import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "../js/objects.js" as Objects -import "../js/historylib.js" as HistoryLib /*! \qmltype ObjectLists \inqmlmodule eu.ad5001.LogarithmPlotter \brief Tab of the drawer that allows the user to manage the objects. - This item allows the user to syntheticly see all objects, while giving the user the ability + This item allows the user to synthetically see all objects, while giving the user the ability to show, hide, delete, change the location and color, as well as opening the editor dialog for each object. @@ -89,146 +88,18 @@ ScrollView { } } - delegate: Item { + delegate: ObjectRow { id: controlRow - property var obj: Objects.currentObjects[objType][index] - property alias objVisible: objVisibilityCheckBox.checked - height: 40 width: objTypeList.width + obj: Objects.currentObjects[objType][index] + posPicker: positionPicker + + onChanged: { + //obj = Objects.currentObjects[objType][index] + objectListList.update() + } Component.onCompleted: objTypeList.editingRows.push(controlRow) - - CheckBox { - id: objVisibilityCheckBox - checked: Objects.currentObjects[objType][index].visible - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 5 - onClicked: { - history.addToHistory(new HistoryLib.EditedVisibility( - Objects.currentObjects[objType][index].name, objType, this.checked - )) - Objects.currentObjects[objType][index].visible = this.checked - objectListList.changed() - controlRow.obj = Objects.currentObjects[objType][index] - } - - ToolTip.visible: hovered - ToolTip.text: checked ? - qsTr("Hide %1 %2").arg(Objects.types[objType].displayType()).arg(obj.name) : - qsTr("Show %1 %2").arg(Objects.types[objType].displayType()).arg(obj.name) - } - - Label { - id: objDescription - anchors.left: objVisibilityCheckBox.right - anchors.right: deleteButton.left - height: parent.height - verticalAlignment: TextInput.AlignVCenter - text: obj.getReadableString() - font.pixelSize: 14 - - MouseArea { - anchors.fill: parent - onClicked: { - objEditor.obj = Objects.currentObjects[objType][index] - objEditor.objType = objType - objEditor.objIndex = index - //objEditor.editingRow = controlRow - objEditor.show() - } - } - } - - Button { - id: pointerButton - width: parent.height - 10 - height: width - anchors.right: deleteButton.left - anchors.rightMargin: 5 - anchors.topMargin: 5 - - Setting.Icon { - id: icon - width: 18 - height: 18 - anchors.centerIn: parent - - color: sysPalette.windowText - source: '../icons/common/position.svg' - } - - property bool hasXProp: Objects.types[objType].properties().hasOwnProperty('x') - property bool hasYProp: Objects.types[objType].properties().hasOwnProperty('y') - visible: hasXProp || hasYProp - ToolTip.visible: hovered - ToolTip.text: qsTr("Set %1 %2 position").arg(Objects.types[objType].displayType()).arg(obj.name) - - onClicked: { - positionPicker.objType = objType - positionPicker.objName = obj.name - positionPicker.pickX = hasXProp - positionPicker.pickY = hasYProp - positionPicker.propertyX = 'x' - positionPicker.propertyY = 'y' - positionPicker.visible = true - - } - } - - Button { - id: deleteButton - width: parent.height - 10 - height: width - anchors.right: colorPickRect.left - anchors.rightMargin: 5 - anchors.topMargin: 5 - icon.name: 'delete' - icon.source: '../icons/common/delete.svg' - icon.color: sysPalette.buttonText - ToolTip.visible: hovered - ToolTip.text: qsTr("Delete %1 %2").arg(Objects.types[objType].displayType()).arg(obj.name) - - onClicked: { - history.addToHistory(new HistoryLib.DeleteObject( - obj.name, objType, obj.export() - )) - Objects.deleteObject(obj.name) - objectListList.update() - } - } - - Rectangle { - id: colorPickRect - anchors.right: parent.right - anchors.rightMargin: 5 - anchors.topMargin: 5 - color: obj.color - width: parent.height - 10 - height: width - radius: Math.min(width, height) - border.width: 2 - border.color: sysPalette.windowText - - MouseArea { - anchors.fill: parent - onClicked: pickColor.open() - } - } - - D.ColorDialog { - id: pickColor - color: obj.color - title: qsTr("Pick new color for %1 %2").arg(Objects.types[objType].displayType()).arg(obj.name) - onAccepted: { - history.addToHistory(new HistoryLib.ColorChanged( - obj.name, objType, obj.color, color.toString() - )) - obj.color = color.toString() - controlRow.obj = Objects.currentObjects[objType][index] - objectListList.update() - } - } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml new file mode 100644 index 0000000..cf91ffc --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -0,0 +1,180 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.12 +import QtQuick.Dialogs 1.3 as D +import QtQuick.Controls 2.12 +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import "../js/objects.js" as Objects +import "../js/historylib.js" as HistoryLib + +/*! + \qmltype ObjectRow + \inqmlmodule eu.ad5001.LogarithmPlotter + \brief Row describing an object. + + This item allows the user to see, control, and modify a graph object. + It includes the visibility checkbox, the description label (optionally latex if enabled), + the reposition and delete buttons, and the color picker. + + + \sa LogarithmPlotter, ObjectCreationGrid, ObjectLists +*/ +Item { + id: objectRow + + signal changed() + + property var obj + property var posPicker + + property alias objVisible: objVisibilityCheckBox.checked + + height: 40 + width: obj.typeList.width + + CheckBox { + id: objVisibilityCheckBox + checked: obj.visible + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 5 + onClicked: { + history.addToHistory(new HistoryLib.EditedVisibility( + obj.name, obj.type, this.checked + )) + obj.visible = this.checked + changed() + } + + ToolTip.visible: hovered + ToolTip.text: checked ? + qsTr("Hide %1 %2").arg(obj.constructor.displayType()).arg(obj.name) : + qsTr("Show %1 %2").arg(obj.constructor.displayType()).arg(obj.name) + } + + Label { + id: objDescription + anchors.left: objVisibilityCheckBox.right + anchors.right: deleteButton.left + height: parent.height + verticalAlignment: TextInput.AlignVCenter + text: obj.getReadableString() + font.pixelSize: 14 + + MouseArea { + anchors.fill: parent + onClicked: { + objEditor.obj = Objects.currentObjects[obj.type][index] + objEditor.obj.type = obj.type + objEditor.objIndex = index + //objEditor.editingRow = objectRow + objEditor.show() + } + } + } + + Button { + id: pointerButton + width: parent.height - 10 + height: width + anchors.right: deleteButton.left + anchors.rightMargin: 5 + anchors.topMargin: 5 + + Setting.Icon { + id: icon + width: 18 + height: 18 + anchors.centerIn: parent + + color: sysPalette.windowText + source: '../icons/common/position.svg' + } + + property bool hasXProp: obj.constructor.properties().hasOwnProperty('x') + property bool hasYProp: obj.constructor.properties().hasOwnProperty('y') + visible: hasXProp || hasYProp + ToolTip.visible: hovered + ToolTip.text: qsTr("Set %1 %2 position").arg(obj.constructor.displayType()).arg(obj.name) + + onClicked: { + posPicker.objType = obj.type + posPicker.objName = obj.name + posPicker.pickX = hasXProp + posPicker.pickY = hasYProp + posPicker.propertyX = 'x' + posPicker.propertyY = 'y' + posPicker.visible = true + + } + } + + Button { + id: deleteButton + width: parent.height - 10 + height: width + anchors.right: colorPickRect.left + anchors.rightMargin: 5 + anchors.topMargin: 5 + icon.name: 'delete' + icon.source: '../icons/common/delete.svg' + icon.color: sysPalette.buttonText + ToolTip.visible: hovered + ToolTip.text: qsTr("Delete %1 %2").arg(obj.constructor.displayType()).arg(obj.name) + + onClicked: { + history.addToHistory(new HistoryLib.DeleteObject( + obj.name, obj.type, obj.export() + )) + Objects.deleteObject(obj.name) + changed() + } + } + + Rectangle { + id: colorPickRect + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.topMargin: 5 + color: obj.color + width: parent.height - 10 + height: width + radius: Math.min(width, height) + border.width: 2 + border.color: sysPalette.windowText + + MouseArea { + anchors.fill: parent + onClicked: pickColor.open() + } + } + + D.ColorDialog { + id: pickColor + color: obj.color + title: qsTr("Pick new color for %1 %2").arg(obj.constructor.displayType()).arg(obj.name) + onAccepted: { + history.addToHistory(new HistoryLib.ColorChanged( + obj.name, obj.type, obj.color, color.toString() + )) + obj.color = color.toString() + changed() + } + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir index 7cbf3ea..1478c34 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir @@ -2,5 +2,5 @@ module eu.ad5001.LogarithmPlotter.ObjectLists ObjectLists 1.0 ObjectLists.qml ObjectCreationGrid 1.0 ObjectCreationGrid.qml +ObjectRow 1.0 ObjectRow.qml EditorDialog 1.0 EditorDialog.qml - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js index 87be759..9641967 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js @@ -116,7 +116,7 @@ class EditedProperty extends C.Action { .arg(this.targetPropertyReadable) .arg(' ' + this.targetName + ' ') .arg(' '+this.prev+' ') - .arg(' '+this.next+'') + .arg(' '+this.next+' ') // .arg('' + Objects.types[this.targetType].displayType()) } From 15fd660e0c58a171d1715aa81de78df2e5fdaad0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 01:47:49 +0200 Subject: [PATCH 026/436] Adding support for latex images in the objects tab. --- .../LogarithmPlotter/ObjectLists/ObjectRow.qml | 14 +++++++++++++- LogarithmPlotter/util/latex.py | 11 ++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index cf91ffc..13cb9df 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -22,6 +22,8 @@ import QtQuick.Controls 2.12 import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "../js/objects.js" as Objects import "../js/historylib.js" as HistoryLib +import "../js/math/latex.js" as LatexJS + /*! \qmltype ObjectRow @@ -74,9 +76,19 @@ Item { anchors.right: deleteButton.left height: parent.height verticalAlignment: TextInput.AlignVCenter - text: obj.getReadableString() + text: LatexJS.enabled ? "" : obj.getReadableString() font.pixelSize: 14 + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + visible: LatexJS.enabled + property var ltxInfo: visible ? Latex.render(obj.getLatexLabel(), 2*parent.font.pixelSize, parent.color).split(",") : ["","0","0"] + source: visible ? ltxInfo[0] : "" + width: parseInt(ltxInfo[1])/2 + height: parseInt(ltxInfo[2])/2 + } + MouseArea { anchors.fill: parent onClicked: { diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 0ce5b91..d9b4643 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -79,11 +79,11 @@ class Latex(QObject): @Property(bool) def latexSupported(self): return LATEX_PATH is not None and DVIPNG_PATH is not None - + @Slot(str, float, QColor, result=str) - def render(self, latex_markup: str, font_size: float, color: QColor = True) -> str: + def render(self, latex_markup: str, font_size: float, color: QColor) -> str: """ - Renders a latex string into a png file. + Prepares and renders a latex string into a png file. """ markup_hash = hash(latex_markup) export_path = path.join(self.tempdir.name, f'{markup_hash}_{font_size}_{color.rgb()}') @@ -100,7 +100,7 @@ class Latex(QObject): self.convert_dvi_to_png(latex_path, export_path, font_size, color) except Exception as e: # One of the processes failed. A message will be sent every time. raise e - img = QImage(export_path + ".png"); + img = QImage(export_path); # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' @@ -171,7 +171,7 @@ class Latex(QObject): for i in [".tex", ".aux", ".log"]: remove(export_path + i) - + """ @Slot(str, float, QColor, result=str) def render_legacy(self, latexstring, font_size, color = True): exprpath = path.join(self.tempdir.name, f'{hash(latexstring)}_{font_size}_{color.rgb()}.png') @@ -190,3 +190,4 @@ class Latex(QObject): img = QImage(exprpath); # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{exprpath},{img.width()},{img.height()}' + """ From 9facc2389cdd9da017b9e26821a527c971ddea0d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 02:00:56 +0200 Subject: [PATCH 027/436] Attempting to fix blurry icons and Latex renders in the objects tab. --- .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml | 7 ++++--- .../qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index cb68524..f58e496 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -47,7 +47,7 @@ ScrollView { ListView { id: objectsListView model: Object.keys(Objects.types) - width: implicitWidth //objectListList.width - (implicitHeight > objectListList.parent.height ? 20 : 0) + //width: implicitWidth //objectListList.width - (implicitHeight > objectListList.parent.height ? 20 : 0) implicitHeight: contentItem.childrenRect.height + footer.height + 10 delegate: ListView { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 13cb9df..617b67f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -83,10 +83,11 @@ Item { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left visible: LatexJS.enabled - property var ltxInfo: visible ? Latex.render(obj.getLatexLabel(), 2*parent.font.pixelSize, parent.color).split(",") : ["","0","0"] + property double depth: 2 + property var ltxInfo: visible ? Latex.render(obj.getLatexLabel(), depth*parent.font.pixelSize, parent.color).split(",") : ["","0","0"] source: visible ? ltxInfo[0] : "" - width: parseInt(ltxInfo[1])/2 - height: parseInt(ltxInfo[2])/2 + width: parseInt(ltxInfo[1])/depth + height: parseInt(ltxInfo[2])/depth } MouseArea { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index d1b7b58..518aca0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -48,6 +48,7 @@ Item { width: parent.width //smooth: true visible: false + sourceSize.width: width*2 sourceSize.height: sourceSize.width } ColorOverlay { From f76b601139d66cad377f5630a256a415266b8807 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 02:55:15 +0200 Subject: [PATCH 028/436] Fixing tons of bugs. 1. Height of object list items should be adaptable to image's heights. 2. Fixed object positioning 3. Buttons of object rows are now vertically centered. 4. Fixing expr-eval not recognizing certain characters as part of the variable. 5. Fixing silent error when misentering variables preventing you from changing the expression again. 6. Fixing points in gains and phases having name-related issues. 7. (in the previous commit) Fixing invisible buttons at the end of the object row when not changing tabs. --- .../ObjectLists/ObjectRow.qml | 21 +++++++++++-------- .../ad5001/LogarithmPlotter/Setting/Icon.qml | 2 +- .../LogarithmPlotter/Setting/TextSetting.qml | 1 - .../ad5001/LogarithmPlotter/js/expr-eval.js | 15 ++++++++++++- .../ad5001/LogarithmPlotter/js/objs/common.js | 6 ++++-- .../LogarithmPlotter/js/objs/gainbode.js | 6 ++---- .../LogarithmPlotter/js/objs/phasebode.js | 5 +---- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 617b67f..b13a293 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -46,8 +46,9 @@ Item { property var posPicker property alias objVisible: objVisibilityCheckBox.checked + property int minHeight: 40 - height: 40 + height: objDescription.height width: obj.typeList.width CheckBox { @@ -74,17 +75,18 @@ Item { id: objDescription anchors.left: objVisibilityCheckBox.right anchors.right: deleteButton.left - height: parent.height + height: LatexJS.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight verticalAlignment: TextInput.AlignVCenter text: LatexJS.enabled ? "" : obj.getReadableString() font.pixelSize: 14 Image { + id: latexDescription anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left visible: LatexJS.enabled property double depth: 2 - property var ltxInfo: visible ? Latex.render(obj.getLatexLabel(), depth*parent.font.pixelSize, parent.color).split(",") : ["","0","0"] + property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*parent.font.pixelSize+4, parent.color).split(",") : ["","0","0"] source: visible ? ltxInfo[0] : "" width: parseInt(ltxInfo[1])/depth height: parseInt(ltxInfo[2])/depth @@ -94,7 +96,7 @@ Item { anchors.fill: parent onClicked: { objEditor.obj = Objects.currentObjects[obj.type][index] - objEditor.obj.type = obj.type + objEditor.objType = obj.type objEditor.objIndex = index //objEditor.editingRow = objectRow objEditor.show() @@ -108,7 +110,7 @@ Item { height: width anchors.right: deleteButton.left anchors.rightMargin: 5 - anchors.topMargin: 5 + anchors.verticalCenter: parent.verticalCenter Setting.Icon { id: icon @@ -127,6 +129,7 @@ Item { ToolTip.text: qsTr("Set %1 %2 position").arg(obj.constructor.displayType()).arg(obj.name) onClicked: { + console.log(obj.type, obj.name) posPicker.objType = obj.type posPicker.objName = obj.name posPicker.pickX = hasXProp @@ -140,11 +143,11 @@ Item { Button { id: deleteButton - width: parent.height - 10 + width: parent.minHeight - 10 height: width anchors.right: colorPickRect.left anchors.rightMargin: 5 - anchors.topMargin: 5 + anchors.verticalCenter: parent.verticalCenter icon.name: 'delete' icon.source: '../icons/common/delete.svg' icon.color: sysPalette.buttonText @@ -164,9 +167,9 @@ Item { id: colorPickRect anchors.right: parent.right anchors.rightMargin: 5 - anchors.topMargin: 5 + anchors.verticalCenter: parent.verticalCenter color: obj.color - width: parent.height - 10 + width: parent.minHeight - 10 height: width radius: Math.min(width, height) border.width: 2 diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index 518aca0..7df012c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -49,7 +49,7 @@ Item { //smooth: true visible: false sourceSize.width: width*2 - sourceSize.height: sourceSize.width + sourceSize.height: width*2 } ColorOverlay { anchors.fill: img diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index d9239c8..e361250 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -165,7 +165,6 @@ Item { "ₜ","¹","²","³","⁴","⁵","⁶", "⁷","⁸","⁹","⁰","₁","₂","₃", "₄","₅","₆","₇","₈","₉","₀" - ] Repeater { model: parent.insertChars.length diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 5056ed2..16c3940 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -16,6 +16,19 @@ var IMEMBER = 'IMEMBER'; var IENDSTATEMENT = 'IENDSTATEMENT'; var IARRAY = 'IARRAY'; +// Additional variable characters. +var ADDITIONAL_VARCHARS = [ + "α","β","γ","δ","ε","ζ","η", + "π","θ","κ","λ","μ","ξ","ρ", + "ς","σ","τ","φ","χ","ψ","ω", + "Γ","Δ","Θ","Λ","Ξ","Π","Σ", + "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", + "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", + "ₜ","¹","²","³","⁴","⁵","⁶", + "⁷","⁸","⁹","⁰","₁","₂","₃", + "₄","₅","₆","₇","₈","₉","₀" + ] + function Instruction(type, value) { this.type = type; this.value = (value !== undefined && value !== null) ? value : 0; @@ -707,7 +720,7 @@ TokenStream.prototype.isName = function () { var hasLetter = false; for (; i < this.expression.length; i++) { var c = this.expression.charAt(i); - if (c.toUpperCase() === c.toLowerCase()) { + if (c.toUpperCase() === c.toLowerCase() && !ADDITIONAL_VARCHARS.includes(c)) { if (i === this.pos && (c === '$' || c === '_')) { if (c === '_') { hasLetter = true; diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index e37ad75..795d0a0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -200,8 +200,10 @@ class DrawableObject { if(properties[property] == 'Expression' && this[property] != null) { // Expressions with dependencies for(let objName of this[property].requiredObjects()) { - this.requires.push(C.currentObjectsByName[objName]) - C.currentObjectsByName[objName].requiredBy.push(this) + if(objName in C.currentObjectsByName) { + this.requires.push(C.currentObjectsByName[objName]) + C.currentObjectsByName[objName].requiredBy.push(this) + } } if(this[property].cached && this[property].requiredObjects().length > 0) // Recalculate diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index a95f53e..265c9e9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -52,11 +52,9 @@ class GainBode extends Common.ExecutableObject { om_0 = Objects.currentObjectsByName[om_0] if(om_0 == null) { // Create new point - om_0 = Objects.createNewRegisteredObject('Point') - om_0.name = Common.getNewName('ω') - om_0.labelContent = 'name' - om_0.color = this.color + om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), true, this.color, 'name']) HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export())) + om_0.update() labelPosition = 'below' } om_0.requiredBy.push(this) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index 63b01a6..5cbd4a9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -51,10 +51,7 @@ class PhaseBode extends Common.ExecutableObject { om_0 = Objects.currentObjectsByName[om_0] if(om_0 == null) { // Create new point - om_0 = Objects.createNewRegisteredObject('Point') - om_0.name = Common.getNewName('ω') - om_0.color = this.color - om_0.labelContent = 'name' + om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), this.color, 'name']) om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below' HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export())) labelPosition = 'below' From d65f343b6002248898e620d880e1e8d019ed9c0b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 16:43:39 +0200 Subject: [PATCH 029/436] Reworking the Editor dialog to be much faster and cleaner. By using Components and Loader instead of instantiating each type of editor for every property, the whole operation becomes much faster, cleaner, and streamlined. Visible (admittedly unmeasured) boosts in speed with it. Preparing the groundwork for new editors. --- .../ObjectLists/Editor/CustomPropertyList.qml | 256 ++++++++++++++ .../ObjectLists/Editor/Dialog.qml | 145 ++++++++ .../ObjectLists/Editor/qmldir | 5 + .../ObjectLists/EditorDialog.qml | 319 ------------------ .../ObjectLists/ObjectLists.qml | 5 +- .../ObjectLists/ObjectRow.qml | 21 +- .../Setting/LatexExpression.qml | 28 -- 7 files changed, 427 insertions(+), 352 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/EditorDialog.qml delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/LatexExpression.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml new file mode 100644 index 0000000..20f3885 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -0,0 +1,256 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Dialogs 1.3 as D +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import "../../js/objects.js" as Objects +import "../../js/objs/common.js" as ObjectsCommons +import "../../js/historylib.js" as HistoryLib +import "../../js/utils.js" as Utils +import "../../js/mathlib.js" as MathLib + +/*! + \qmltype CustomPropertyList + \inqmlmodule eu.ad5001.LogarithmPlotter.ObjectLists.Editor + \brief Lists all custom properties editors inside a repeater and allow for edition. + + This class repeats all of the custom properties and loads the appropriate editor for each kind of property. + + \sa Dialog +*/ +Repeater { + id: dlgCustomProperties + + signal changed() + + /*! + \qmlproperty var CustomPropertyList::obj + Object whose properties to list and edit. + */ + property var obj + + readonly property var textTypes: ['Expression', 'Domain', 'string', 'number'] + readonly property var comboBoxTypes: ['ObjectType', 'Enum'] + readonly property var listTypes: ['List', 'Dict'] + + + // NOTE: All components have the declared properties 'propertyLabel', 'propertyIcon', propertyName' and 'propertyType' to access the object in question. + Component { + id: commentComponent + + // Item for comments. + // NOTE: propertyType here is the content of the comment (yes, it's a bit backwards, but it's more clear on the properties side). + Label { + // Translated text with object name. + property string trText: qsTranslate('comment', propertyType).toString() + text: (trText.includes("%1") ? trText.arg(obj.name) : trText).toString() + //color: sysPalette.windowText + wrapMode: Text.WordWrap + } + } + + Component { + id: textEditorComponent + + // Setting for text & number settings as well as domains & expressions + Setting.TextSetting { + height: 30 + label: propertyLabel + icon: `settings/custom/${propertyIcon}.svg` + isDouble: propertyType == 'number' + defValue: { + switch(propertyType) { + case 'Expression': + return Utils.simplifyExpression(obj[propertyName].toEditableString()) + break + case 'string': + return obj[propertyName] + break + case 'Domain': + case 'number': + default: + return obj[propertyName].toString() + } + } + onChanged: function(newValue) { + var newValue = { + 'Expression': () => new MathLib.Expression(newValue), + 'Domain': () => MathLib.parseDomain(newValue), + 'string': () => newValue, + 'number': () => parseFloat(newValue) + }[propertyType]() + // Ensuring old and new values are different to prevent useless adding to history. + if(obj[propertyName] != newValue) { + history.addToHistory(new HistoryLib.EditedProperty( + obj.name, objType, propertyName, + obj[propertyName], newValue + )) + obj[propertyName] = newValue + Objects.currentObjects[objType][objIndex].update() + objectListList.update() + } + } + } + } + + Component { + id: checkboxComponent + + // Setting for boolean + CheckBox { + height: 20 + text: propertyLabel + //icon: `settings/custom/${propertyIcon}.svg` + + checked: obj[propertyName] + onClicked: { + history.addToHistory(new HistoryLib.EditedProperty( + obj.name, objType, propertyName, + obj[propertyName], this.checked + )) + obj[propertyName] = this.checked + Objects.currentObjects[objType][objIndex].update() + objectListList.update() + } + } + } + + Component { + id: comboBoxComponent + + // Setting when selecting data from an enum, or an object of a certain type. + Setting.ComboBoxSetting { + height: 30 + label: propertyLabel + icon: `settings/custom/${propertyIcon}.svg` + // True to select an object of type, false for enums. + property bool selectObjMode: paramTypeIn(propertyType, ['ObjectType']) + property bool isRealObject: !selectObjMode || (propertyType.objType != "ExecutableObject" && propertyType.objType != "DrawableObject") + + // Base, untranslated version of the model. + property var baseModel: selectObjMode ? + Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Objects.types[propertyType.objType].displayType())] : []) + : propertyType.values + // Translated version of the model. + model: selectObjMode ? baseModel : propertyType.translatedValues + currentIndex: baseModel.indexOf(selectObjMode ? obj[propertyName].name : obj[propertyName]) + + onActivated: function(newIndex) { + if(selectObjMode) { + // This is only done when what we're selecting are Objects. + // Setting object property. + var selectedObj = Objects.currentObjectsByName[baseModel[newIndex]] + if(newIndex != 0) { + // Make sure we don't set the object to null. + if(selectedObj == null) { + // Creating new object. + selectedObj = Objects.createNewRegisteredObject(propertyType.objType) + history.addToHistory(new HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export())) + baseModel = Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Objects.types[propertyType.objType].displayType())] : + []) + currentIndex = baseModel.indexOf(selectedObj.name) + } + selectedObj.requiredBy.push(Objects.currentObjects[objType][objIndex]) + //Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) + } + obj.requiredBy = obj.requiredBy.filter((obj) => obj.name != obj.name) + history.addToHistory(new HistoryLib.EditedProperty( + obj.name, objType, propertyName, + obj[propertyName], selectedObj + )) + obj[propertyName] = selectedObj + } else if(baseModel[newIndex] != obj[propertyName]) { + // Ensuring new property is different to not add useless history entries. + history.addToHistory(new HistoryLib.EditedProperty( + obj.name, objType, propertyName, + obj[propertyName], baseModel[newIndex] + )) + obj[propertyName] = baseModel[newIndex] + } + // Refreshing + Objects.currentObjects[objType][objIndex].update() + objectListList.update() + } + } + } + + Component { + // Setting to edit lists or dictionaries (e.g sequences & repartition function values) + id: listDictEditorComponent + + Setting.ListSetting { + label: propertyLabel + //icon: `settings/custom/${propertyIcon}.svg` + dictionaryMode: paramTypeIn(propertyType, ['Dict']) + keyType: dictionaryMode ? propertyType.keyType : 'string' + valueType: propertyType.valueType + preKeyLabel: (dictionaryMode ? propertyType.preKeyLabel : propertyType.label).replace(/\{name\}/g, obj.name) + postKeyLabel: (dictionaryMode ? propertyType.postKeyLabel : '').replace(/\{name\}/g, obj.name) + keyRegexp: dictionaryMode ? propertyType.keyFormat : /^.+$/ + valueRegexp: propertyType.format + forbidAdding: propertyType.forbidAdding + + onChanged: { + var exported = exportModel() + history.addToHistory(new HistoryLib.EditedProperty( + obj.name, objType, propertyName, + obj[propertyName], exported + )) + //Objects.currentObjects[objType][objIndex][propertyName] = exported + obj[propertyName] = exported + //Objects.currentObjects[objType][objIndex].update() + obj.update() + objectListList.update() + } + + Component.onCompleted: { + importModel(obj[propertyName]) + } + } + } + + delegate: Component { + Loader { + //height: customPropComment.height + customPropText.height + customPropCheckBox.height + customPropCombo.height + customPropListDict.height + width: dlgProperties.width + property string propertyName: modelData[0] + property var propertyType: modelData[1] + property string propertyLabel: qsTranslate('prop',propertyName) + property string propertyIcon: Utils.camelCase2readable(propertyName) + + sourceComponent: { + if(propertyName.startsWith('comment')) + return commentComponent + else if(propertyType == 'boolean') + return checkboxComponent + else if(paramTypeIn(propertyType, textTypes)) + return textEditorComponent + else if(paramTypeIn(propertyType, comboBoxTypes)) + return comboBoxComponent + else if(paramTypeIn(propertyType, listTypes)) + return listDictEditorComponent + else + return {} + } + } + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml new file mode 100644 index 0000000..bc6cdd7 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -0,0 +1,145 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Dialogs 1.3 as D +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import "../../js/objects.js" as Objects +import "../../js/objs/common.js" as ObjectsCommons +import "../../js/historylib.js" as HistoryLib +import "../../js/utils.js" as Utils +import "../../js/mathlib.js" as MathLib + +/*! + \qmltype Dialog + \inqmlmodule eu.ad5001.LogarithmPlotter.ObjectLists.Editor + \brief Dialog used to edit properties of objects. + + This class contains the dialog that allows to edit all properties of objects. + \todo In the future, this class should be optimized so that each property doesn't instanciate one instance of each setting type. + + \sa Loader, ObjectLists +*/ +D.Dialog { + id: objEditor + /*! + \qmlproperty string EditorDialog::objType + Type of object being edited by the dialog. + */ + property string objType: 'Point' + /*! + \qmlproperty int EditorDialog::objIndex + Index of the objects amongst the ones of it's type. + */ + property int objIndex: 0 + /*! + \qmlproperty var EditorDialog::obj + Instance of the object being edited. + */ + property var obj: Objects.currentObjects[objType][objIndex] + + title: "LogarithmPlotter" + width: 350 + height: 400 + + Label { + id: dlgTitle + anchors.left: parent.left + anchors.top: parent.top + verticalAlignment: TextInput.AlignVCenter + text: qsTr("Edit properties of %1 %2").arg(Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) + font.pixelSize: 20 + color: sysPalette.windowText + } + + Column { + id: dlgProperties + anchors.top: dlgTitle.bottom + width: objEditor.width - 20 + spacing: 10 + + D.MessageDialog { + id: invalidNameDialog + title: qsTr("LogarithmPlotter - Invalid object name") + text: "" + function showDialog(objectName) { + text = qsTr("An object with the name '%1' already exists.").arg(objectName) + open() + } + } + + Setting.TextSetting { + id: nameProperty + height: 30 + label: qsTr("Name") + icon: "common/label.svg" + width: dlgProperties.width + value: objEditor.obj.name + onChanged: function(newValue) { + let newName = Utils.parseName(newValue) + if(newName != '' && objEditor.obj.name != newName) { + if(newName in Objects.currentObjectsByName) { + invalidNameDialog.showDialog(newName) + } else { + history.addToHistory(new HistoryLib.NameChanged( + objEditor.obj.name, objEditor.objType, newName + )) + Objects.renameObject(obj.name, newName) + objEditor.obj = Objects.currentObjects[objEditor.objType][objEditor.objIndex] + objectListList.update() + } + } + } + } + + Setting.ComboBoxSetting { + id: labelContentProperty + height: 30 + width: dlgProperties.width + label: qsTr("Label content") + model: [qsTr("null"), qsTr("name"), qsTr("name + value")] + property var idModel: ["null", "name", "name + value"] + icon: "common/label.svg" + currentIndex: idModel.indexOf(objEditor.obj.labelContent) + onActivated: function(newIndex) { + if(idModel[newIndex] != objEditor.obj.labelContent) { + objEditor.obj.labelContent = idModel[newIndex] + objectListList.update() + } + } + } + + // Dynamic properties + CustomPropertyList { + id: dlgCustomProperties + obj: objEditor.obj + } + } + + /*! + \qmlmethod void EditorDialog::show() + Shows the editor after the object to be edited is set. + */ + function show() { + dlgCustomProperties.model = [] // Reset + let objProps = Objects.types[objEditor.objType].properties() + dlgCustomProperties.model = Object.keys(objProps).map(prop => [prop, objProps[prop]]) // Converted to 2-dimentional array. + objEditor.open() + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir new file mode 100644 index 0000000..feb9724 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/qmldir @@ -0,0 +1,5 @@ +module eu.ad5001.LogarithmPlotter.ObjectLists.Editor + +Dialog 1.0 Dialog.qml +CustomPropertyList 1.0 CustomPropertyList.qml + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/EditorDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/EditorDialog.qml deleted file mode 100644 index 9cf4a12..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/EditorDialog.qml +++ /dev/null @@ -1,319 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import QtQuick 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Dialogs 1.3 as D -import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/objects.js" as Objects -import "../js/objs/common.js" as ObjectsCommons -import "../js/historylib.js" as HistoryLib -import "../js/utils.js" as Utils -import "../js/mathlib.js" as MathLib - -/*! - \qmltype EditorDialog - \inqmlmodule eu.ad5001.LogarithmPlotter.ObjectLists - \brief Dialog used to edit properties of objects. - - This class contains the dialog that allows to edit all properties of objects. - \todo In the future, this class should be optimized so that each property doesn't instanciate one instance of each setting type. - - \sa LogarithmPlotter, ObjectLists -*/ -D.Dialog { - id: objEditor - /*! - \qmlproperty string EditorDialog::objType - Type of object being edited by the dialog. - */ - property string objType: 'Point' - /*! - \qmlproperty int EditorDialog::objIndex - Index of the objects amongst the ones of it's type. - */ - property int objIndex: 0 - /*! - \qmlproperty var EditorDialog::obj - Instance of the object being edited. - */ - property var obj: Objects.currentObjects[objType][objIndex] - - title: "LogarithmPlotter" - width: 350 - height: 400 - - Label { - id: dlgTitle - anchors.left: parent.left - anchors.top: parent.top - verticalAlignment: TextInput.AlignVCenter - text: qsTr("Edit properties of %1 %2").arg(Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) - font.pixelSize: 20 - color: sysPalette.windowText - } - - Column { - id: dlgProperties - anchors.top: dlgTitle.bottom - width: objEditor.width - 20 - spacing: 10 - - D.MessageDialog { - id: invalidNameDialog - title: qsTr("LogarithmPlotter - Invalid object name") - text: "" - function showDialog(objectName) { - text = qsTr("An object with the name '%1' already exists.").arg(objectName) - open() - } - } - - Setting.TextSetting { - id: nameProperty - height: 30 - label: qsTr("Name") - icon: "common/label.svg" - width: dlgProperties.width - value: objEditor.obj.name - onChanged: function(newValue) { - let newName = Utils.parseName(newValue) - if(newName != '' && objEditor.obj.name != newName) { - if(newName in Objects.currentObjectsByName) { - invalidNameDialog.showDialog(newName) - } else { - history.addToHistory(new HistoryLib.NameChanged( - objEditor.obj.name, objEditor.objType, newName - )) - Objects.renameObject(obj.name, newName) - objEditor.obj = Objects.currentObjects[objEditor.objType][objEditor.objIndex] - objectListList.update() - } - } - } - } - - Setting.ComboBoxSetting { - id: labelContentProperty - height: 30 - width: dlgProperties.width - label: qsTr("Label content") - model: [qsTr("null"), qsTr("name"), qsTr("name + value")] - property var idModel: ["null", "name", "name + value"] - icon: "common/label.svg" - currentIndex: idModel.indexOf(objEditor.obj.labelContent) - onActivated: function(newIndex) { - if(idModel[newIndex] != objEditor.obj.labelContent) { - objEditor.obj.labelContent = idModel[newIndex] - objectListList.update() - } - } - } - - // Dynamic properties - Repeater { - id: dlgCustomProperties - - Item { - height: customPropComment.height + customPropText.height + customPropCheckBox.height + customPropCombo.height + customPropListDict.height - width: dlgProperties.width - property string label: qsTranslate('prop',modelData[0]) - property string icon: Utils.camelCase2readable(modelData[0]) - - // Item for comments - Label { - id: customPropComment - width: parent.width - height: visible ? implicitHeight : 0 - visible: modelData[0].startsWith('comment') - // Translated text with object name. - property string trText: visible ? qsTranslate('comment', modelData[1]).toString() : '' - text: (visible && trText.includes("%1") ? trText.arg(objEditor.obj.name) : trText).toString() - //color: sysPalette.windowText - wrapMode: Text.WordWrap - } - - // Setting for text & number settings as well as domains & expressions - Setting.TextSetting { - id: customPropText - height: visible ? 30 : 0 - width: parent.width - label: parent.label - icon: `settings/custom/${parent.icon}.svg` - isDouble: modelData[1] == 'number' - visible: paramTypeIn(modelData[1], ['Expression', 'Domain', 'string', 'number']) - defValue: visible ? { - 'Expression': () => Utils.simplifyExpression(objEditor.obj[modelData[0]].toEditableString()), - 'Domain': () => objEditor.obj[modelData[0]].toString(), - 'string': () => objEditor.obj[modelData[0]], - 'number': () => objEditor.obj[modelData[0]] - }[modelData[1]]() : "" - onChanged: function(newValue) { - var newValue = { - 'Expression': () => new MathLib.Expression(newValue), - 'Domain': () => MathLib.parseDomain(newValue), - 'string': () => newValue, - 'number': () => parseFloat(newValue) - }[modelData[1]]() - // Ensuring old and new values are different to prevent useless adding to history. - if(objEditor.obj[modelData[0]] != newValue) { - history.addToHistory(new HistoryLib.EditedProperty( - objEditor.obj.name, objEditor.objType, modelData[0], - objEditor.obj[modelData[0]], newValue - )) - objEditor.obj[modelData[0]] = newValue - Objects.currentObjects[objEditor.objType][objEditor.objIndex].update() - objectListList.update() - } - } - } - - // Setting for boolean - CheckBox { - id: customPropCheckBox - visible: modelData[1] == 'boolean' - height: visible ? 20 : 0 - width: parent.width - text: parent.label - //icon: visible ? `settings/custom/${parent.icon}.svg` : '' - - checked: visible ? objEditor.obj[modelData[0]] : false - onClicked: { - history.addToHistory(new HistoryLib.EditedProperty( - objEditor.obj.name, objEditor.objType, modelData[0], - objEditor.obj[modelData[0]], this.checked - )) - objEditor.obj[modelData[0]] = this.checked - Objects.currentObjects[objEditor.objType][objEditor.objIndex].update() - objectListList.update() - } - } - - // Setting when selecting data from an enum, or an object of a certain type. - Setting.ComboBoxSetting { - id: customPropCombo - width: dlgProperties.width - height: visible ? 30 : 0 - label: parent.label - icon: visible ? `settings/custom/${parent.icon}.svg` : '' - // True to select an object of type, false for enums. - property bool selectObjMode: paramTypeIn(modelData[1], ['ObjectType']) - property bool isRealObject: !selectObjMode || (modelData[1].objType != "ExecutableObject" && modelData[1].objType != "DrawableObject") - - // Base, untranslated version of the model. - property var baseModel: visible ? - (selectObjMode ? - Objects.getObjectsName(modelData[1].objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Objects.types[modelData[1].objType].displayType())] : - []) : - modelData[1].values) - : [] - // Translated version of the model. - model: selectObjMode ? baseModel : modelData[1].translatedValues - visible: paramTypeIn(modelData[1], ['ObjectType', 'Enum']) - currentIndex: baseModel.indexOf(selectObjMode ? objEditor.obj[modelData[0]].name : objEditor.obj[modelData[0]]) - - onActivated: function(newIndex) { - if(selectObjMode) { - // This is only done when what we're selecting are Objects. - // Setting object property. - var selectedObj = Objects.currentObjectsByName[baseModel[newIndex]] - if(newIndex != 0) { - // Make sure we don't set the object to null. - if(selectedObj == null) { - // Creating new object. - selectedObj = Objects.createNewRegisteredObject(modelData[1].objType) - history.addToHistory(new HistoryLib.CreateNewObject(selectedObj.name, modelData[1].objType, selectedObj.export())) - baseModel = Objects.getObjectsName(modelData[1].objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Objects.types[modelData[1].objType].displayType())] : - []) - currentIndex = baseModel.indexOf(selectedObj.name) - } - selectedObj.requiredBy.push(Objects.currentObjects[objEditor.objType][objEditor.objIndex]) - //Objects.currentObjects[objEditor.objType][objEditor.objIndex].requiredBy = objEditor.obj[modelData[0]].filter((obj) => objEditor.obj.name != obj.name) - } - objEditor.obj.requiredBy = objEditor.obj.requiredBy.filter((obj) => objEditor.obj.name != obj.name) - history.addToHistory(new HistoryLib.EditedProperty( - objEditor.obj.name, objEditor.objType, modelData[0], - objEditor.obj[modelData[0]], selectedObj - )) - objEditor.obj[modelData[0]] = selectedObj - } else if(baseModel[newIndex] != objEditor.obj[modelData[0]]) { - // Ensuring new property is different to not add useless history entries. - history.addToHistory(new HistoryLib.EditedProperty( - objEditor.obj.name, objEditor.objType, modelData[0], - objEditor.obj[modelData[0]], baseModel[newIndex] - )) - objEditor.obj[modelData[0]] = baseModel[newIndex] - } - // Refreshing - Objects.currentObjects[objEditor.objType][objEditor.objIndex].update() - objectListList.update() - } - } - - // Setting to edit lists or dictionaries (e.g sequences & repartition function values) - Setting.ListSetting { - id: customPropListDict - width: parent.width - height: visible ? implicitHeight : 0 - - visible: paramTypeIn(modelData[1], ['List', 'Dict']) - label: parent.label - //icon: `settings/custom/${parent.icon}.svg` - dictionaryMode: paramTypeIn(modelData[1], ['Dict']) - keyType: dictionaryMode ? modelData[1].keyType : 'string' - valueType: visible ? modelData[1].valueType : 'string' - preKeyLabel: visible ? (dictionaryMode ? modelData[1].preKeyLabel : modelData[1].label).replace(/\{name\}/g, objEditor.obj.name) : '' - postKeyLabel: visible ? (dictionaryMode ? modelData[1].postKeyLabel : '').replace(/\{name\}/g, objEditor.obj.name) : '' - keyRegexp: dictionaryMode ? modelData[1].keyFormat : /^.+$/ - valueRegexp: visible ? modelData[1].format : /^.+$/ - forbidAdding: visible ? modelData[1].forbidAdding : false - - onChanged: { - var exported = exportModel() - history.addToHistory(new HistoryLib.EditedProperty( - objEditor.obj.name, objEditor.objType, modelData[0], - objEditor.obj[modelData[0]], exported - )) - //Objects.currentObjects[objEditor.objType][objEditor.objIndex][modelData[0]] = exported - objEditor.obj[modelData[0]] = exported - //Objects.currentObjects[objEditor.objType][objEditor.objIndex].update() - objEditor.obj.update() - objectListList.update() - } - - Component.onCompleted: { - if(visible) importModel(objEditor.obj[modelData[0]]) - } - } - } - } - } - - /*! - \qmlmethod void EditorDialog::show() - Shows the editor after the object to be edited is set. - */ - function show() { - dlgCustomProperties.model = [] // Reset - let objProps = Objects.types[objEditor.objType].properties() - dlgCustomProperties.model = Object.keys(objProps).map(prop => [prop, objProps[prop]]) // Converted to 2-dimentional array. - objEditor.open() - } -} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index f58e496..0d215ab 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -20,11 +20,12 @@ import QtQuick 2.12 import QtQuick.Dialogs 1.3 as D import QtQuick.Controls 2.12 import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import eu.ad5001.LogarithmPlotter.ObjectLists.Editor 1.0 as Editor import "../js/objects.js" as Objects /*! \qmltype ObjectLists - \inqmlmodule eu.ad5001.LogarithmPlotter + \inqmlmodule eu.ad5001.LogarithmPlotter.ObjectLists \brief Tab of the drawer that allows the user to manage the objects. This item allows the user to synthetically see all objects, while giving the user the ability @@ -113,7 +114,7 @@ ScrollView { } // Object editor - EditorDialog { + Editor.Dialog { id: objEditor } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index b13a293..ddc73eb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -27,14 +27,13 @@ import "../js/math/latex.js" as LatexJS /*! \qmltype ObjectRow - \inqmlmodule eu.ad5001.LogarithmPlotter + \inqmlmodule eu.ad5001.LogarithmPlotter.ObjectLists \brief Row describing an object. This item allows the user to see, control, and modify a graph object. It includes the visibility checkbox, the description label (optionally latex if enabled), the reposition and delete buttons, and the color picker. - \sa LogarithmPlotter, ObjectCreationGrid, ObjectLists */ Item { @@ -42,11 +41,27 @@ Item { signal changed() + /*! + \qmlproperty var ObjectRow::obj + Object to show. + */ property var obj + /*! + \qmlproperty var ObjectRow::posPicker + Reference to the global PositionPicker QML object. + */ property var posPicker + /*! + \qmlproperty bool ObjectRow::objVisible + True if the object should be visible, false otherwise. + */ property alias objVisible: objVisibilityCheckBox.checked - property int minHeight: 40 + /*! + \qmlproperty bool ObjectRow::minHeight + Minimum height of the row. + */ + readonly property int minHeight: 40 height: objDescription.height width: obj.typeList.width diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/LatexExpression.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/LatexExpression.qml deleted file mode 100644 index bc8897c..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/LatexExpression.qml +++ /dev/null @@ -1,28 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -import QtQuick 2.12 -import QtQuick.Controls 2.12 - -Image { - id: expr - property string expression - - src: Latex.render(expression).split(',')[0] -} From 29e62fee6ee82ee6eb2c6d7953eeabb8f26f5bfd Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 17:49:49 +0200 Subject: [PATCH 030/436] Trying to fix deb build --- .../qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir | 1 - linux/flatpak | 2 +- setup.py | 11 +++-------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir index 1478c34..cc26d7a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/qmldir @@ -3,4 +3,3 @@ module eu.ad5001.LogarithmPlotter.ObjectLists ObjectLists 1.0 ObjectLists.qml ObjectCreationGrid 1.0 ObjectCreationGrid.qml ObjectRow 1.0 ObjectRow.qml -EditorDialog 1.0 EditorDialog.qml diff --git a/linux/flatpak b/linux/flatpak index a23d256..f215689 160000 --- a/linux/flatpak +++ b/linux/flatpak @@ -1 +1 @@ -Subproject commit a23d256b5838751f6aadaa9281aceee9ba058047 +Subproject commit f215689b354e07b0fc2e6ad6d0213fe873d497dc diff --git a/setup.py b/setup.py index e3fb347..ea494cc 100644 --- a/setup.py +++ b/setup.py @@ -100,6 +100,8 @@ if sys.platform == 'linux': data_files.append((os.environ["PREFIX"] + '/mime/packages/', ['linux/x-logarithm-plot.xml'])) data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg'])) data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['logplotter.svg'])) + if "FLATPAK_INSTALL" not in os.environ: + data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['logplotter.svg'])) if len(sys.argv) > 1: if sys.argv[1] == "install": os.makedirs(os.environ["PREFIX"] + '/applications/', exist_ok=True) @@ -111,14 +113,7 @@ if sys.platform == 'linux': copyfile(current_dir + '/linux/application-x-logarithm-plot.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg') copyfile(current_dir + '/logplotter.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') - if "FLATPAK_INSTALL" in os.environ: - copyfile(current_dir + '/linux/eu.ad5001.LogarithmPlotter.metainfo.flatpak.xml', - os.environ["PREFIX"] + '/metainfo/eu.ad5001.LogarithmPlotter.metainfo.xml') - copyfile(current_dir + '/linux/flatpak/logarithmplotter.desktop', - os.environ["PREFIX"] + '/applications/logarithmplotter.desktop') - else: - copyfile(current_dir + '/linux/eu.ad5001.LogarithmPlotter.metainfo.xml', - os.environ["PREFIX"] + '/metainfo/eu.ad5001.LogarithmPlotter.metainfo.xml') + #copyfile(current_dir + '/linux/eu.ad5001.LogarithmPlotter.metainfo.xml', os.environ["PREFIX"] + '/metainfo/eu.ad5001.LogarithmPlotter.metainfo.xml') #copyfile(current_dir + '/linux/logarithmplotter.desktop', os.environ["PREFIX"] + '/applications/logarithmplotter.desktop') elif sys.argv[1] == "uninstall": os.remove(os.environ["PREFIX"] + '/applications/logarithmplotter.desktop') From 2a8cab93987a5f20bbaaf209466583c22b0d6b42 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 18:31:04 +0200 Subject: [PATCH 031/436] Proper error handling and reporting for expressions! Only remaining non convered case is recursive dependencies, but I'm not willing to tackle that yet. --- .../ObjectLists/Editor/CustomPropertyList.qml | 73 +++++++++++----- .../ObjectLists/Editor/Dialog.qml | 6 ++ .../ObjectLists/ObjectRow.qml | 1 - .../ad5001/LogarithmPlotter/js/expr-eval.js | 86 +++++++++++-------- .../LogarithmPlotter/js/math/expression.js | 4 + 5 files changed, 108 insertions(+), 62 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 20f3885..0bb35bb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -36,7 +36,7 @@ import "../../js/mathlib.js" as MathLib \sa Dialog */ Repeater { - id: dlgCustomProperties + id: root signal changed() @@ -90,21 +90,52 @@ Repeater { } } onChanged: function(newValue) { - var newValue = { - 'Expression': () => new MathLib.Expression(newValue), - 'Domain': () => MathLib.parseDomain(newValue), - 'string': () => newValue, - 'number': () => parseFloat(newValue) - }[propertyType]() - // Ensuring old and new values are different to prevent useless adding to history. - if(obj[propertyName] != newValue) { - history.addToHistory(new HistoryLib.EditedProperty( - obj.name, objType, propertyName, - obj[propertyName], newValue - )) - obj[propertyName] = newValue - Objects.currentObjects[objType][objIndex].update() - objectListList.update() + try { + var newValueParsed = { + 'Expression': () => { + let expr = new MathLib.Expression(newValue) + // Check if the expression is valid, throws error otherwise. + if(!expr.allRequirementsFullfilled()) { + let undefVars = expr.undefinedVariables() + console.log(JSON.stringify(undefVars), undefVars.join(', ')) + if(undefVars.length > 1) + throw new Error(qsTranslate('error', 'No object found with names %1.').arg(undefVars.join(', '))) + else + throw new Error(qsTranslate('error', 'No object found with name %1.').arg(undefVars.join(', '))) + } + if(expr.requiredObjects().includes(obj.name)) + throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) + // TODO: Check for recursive dependencies. + return expr + }, + 'Domain': () => MathLib.parseDomain(newValue), + 'string': () => newValue, + 'number': () => parseFloat(newValue) + }[propertyType]() + + // Ensuring old and new values are different to prevent useless adding to history. + if(obj[propertyName] != newValueParsed) { + history.addToHistory(new HistoryLib.EditedProperty( + obj.name, objType, propertyName, + obj[propertyName], newValueParsed + )) + obj[propertyName] = newValueParsed + root.changed() + } + } catch(e) { + // Error in expression or domain + parsingErrorDialog.showDialog(propertyName, newValue, e.message) + } + } + + + D.MessageDialog { + id: parsingErrorDialog + title: qsTr("LogarithmPlotter - Parsing error") + text: "" + function showDialog(propName, propValue, error) { + text = qsTr("Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3").arg(propName).arg(error).arg(propValue) + open() } } } @@ -126,8 +157,7 @@ Repeater { obj[propertyName], this.checked )) obj[propertyName] = this.checked - Objects.currentObjects[objType][objIndex].update() - objectListList.update() + root.changed() } } } @@ -187,8 +217,7 @@ Repeater { obj[propertyName] = baseModel[newIndex] } // Refreshing - Objects.currentObjects[objType][objIndex].update() - objectListList.update() + root.changed() } } } @@ -217,9 +246,7 @@ Repeater { )) //Objects.currentObjects[objType][objIndex][propertyName] = exported obj[propertyName] = exported - //Objects.currentObjects[objType][objIndex].update() - obj.update() - objectListList.update() + root.changed() } Component.onCompleted: { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index bc6cdd7..d8c319e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -120,6 +120,7 @@ D.Dialog { onActivated: function(newIndex) { if(idModel[newIndex] != objEditor.obj.labelContent) { objEditor.obj.labelContent = idModel[newIndex] + objEditor.obj.update() objectListList.update() } } @@ -129,6 +130,11 @@ D.Dialog { CustomPropertyList { id: dlgCustomProperties obj: objEditor.obj + + onChanged: { + obj.update() + objectListList.update() + } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index ddc73eb..3937c4f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -144,7 +144,6 @@ Item { ToolTip.text: qsTr("Set %1 %2 position").arg(obj.constructor.displayType()).arg(obj.name) onClicked: { - console.log(obj.type, obj.name) posPicker.objType = obj.type posPicker.objName = obj.name posPicker.pickX = hasXProp diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 16c3940..c615305 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -18,16 +18,16 @@ var IARRAY = 'IARRAY'; // Additional variable characters. var ADDITIONAL_VARCHARS = [ - "α","β","γ","δ","ε","ζ","η", - "π","θ","κ","λ","μ","ξ","ρ", - "ς","σ","τ","φ","χ","ψ","ω", - "Γ","Δ","Θ","Λ","Ξ","Π","Σ", - "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", - "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", - "ₜ","¹","²","³","⁴","⁵","⁶", - "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀" - ] + "α","β","γ","δ","ε","ζ","η", + "π","θ","κ","λ","μ","ξ","ρ", + "ς","σ","τ","φ","χ","ψ","ω", + "Γ","Δ","Θ","Λ","Ξ","Π","Σ", + "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", + "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", + "ₜ","¹","²","³","⁴","⁵","⁶", + "⁷","⁸","⁹","⁰","₁","₂","₃", + "₄","₅","₆","₇","₈","₉","₀" +] function Instruction(type, value) { this.type = type; @@ -117,7 +117,11 @@ function simplify(tokens, unaryOps, binaryOps, ternaryOps, values) { newexpression.push(new Instruction(IEXPR, simplify(item.value, unaryOps, binaryOps, ternaryOps, values))); } else if (type === IMEMBER && nstack.length > 0) { n1 = nstack.pop(); - nstack.push(new Instruction(INUMBER, n1.value[item.value])); + //console.log("Getting property ", item.value, "of", n1) + if(item.value in n1.value) + nstack.push(new Instruction(INUMBER, n1.value[item.value])); + else + throw new Error(qsTranslate('error', 'Cannot find property %1 of object %2.').arg(item.value).arg(n1)) } /* else if (type === IARRAY && nstack.length >= item.value) { var length = item.value; while (length-- > 0) { @@ -217,7 +221,7 @@ function evaluate(tokens, expr, values) { if (v !== undefined) { nstack.push(v); } else { - throw new Error('undefined variable: ' + item.value); + throw new Error(qsTranslate('error', 'Undefined variable %1.').arg(item.value)); } } } else if (type === IOP1) { @@ -237,7 +241,7 @@ function evaluate(tokens, expr, values) { // Objects & expressions execution nstack.push(f.execute.apply(f, args)); } else { - throw new Error(f + ' cannot be executed'); + throw new Error(qsTranslate('error', '%1 cannot be executed.').arg(f)); } } else if (type === IFUNDEF) { // Create closure to keep references to arguments and expression @@ -270,7 +274,11 @@ function evaluate(tokens, expr, values) { nstack.push(item); } else if (type === IMEMBER) { n1 = nstack.pop(); - nstack.push(n1[item.value]); + //console.log("Getting property", item.value, "of", n1) + if(item.value in n1) + nstack.push(n1[item.value]); + else + throw new Error(qsTranslate('error', 'Cannot find property %1 of object %2.').arg(item.value).arg(n1)) } else if (type === IENDSTATEMENT) { nstack.pop(); } else if (type === IARRAY) { @@ -281,11 +289,11 @@ function evaluate(tokens, expr, values) { } nstack.push(args); } else { - throw new Error('invalid Expression'); + throw new Error(qsTranslate('error', 'Invalid expression.')); } } if (nstack.length > 1) { - throw new Error('invalid Expression (parity)'); + throw new Error(qsTranslate('error', 'Invalid expression (parity).')); } // Explicitly return zero to avoid test issues caused by -0 return nstack[0] === 0 ? 0 : resolveExpression(nstack[0], values); @@ -361,7 +369,7 @@ function expressionToString(tokens, toJS) { if (f === '?') { nstack.push('(' + n1 + ' ? ' + n2 + ' : ' + n3 + ')'); } else { - throw new Error('invalid Expression'); + throw new Error(qsTranslate('error', 'Invalid expression.')); } } else if (type === IVAR || type === IVARNAME) { nstack.push(item.value); @@ -417,7 +425,7 @@ function expressionToString(tokens, toJS) { } else if (type === IEXPR) { nstack.push('(' + expressionToString(item.value, toJS) + ')'); } else if (type === IENDSTATEMENT) ; else { - throw new Error('invalid Expression'); + throw new Error(qsTranslate('error', 'Invalid expression.')); } } if (nstack.length > 1) { @@ -605,7 +613,7 @@ TokenStream.prototype.next = function () { this.isName()) { return this.current; } else { - this.parseError('Unknown character "' + this.expression.charAt(this.pos) + '"'); + this.parseError(qsTranslate('error', 'Unknown character "%1".').arg(this.expression.charAt(this.pos))); } }; @@ -799,13 +807,13 @@ TokenStream.prototype.unescape = function (v) { // interpret the following 4 characters as the hex of the unicode code point var codePoint = v.substring(index + 1, index + 5); if (!codePointPattern.test(codePoint)) { - this.parseError('Illegal escape sequence: \\u' + codePoint); + this.parseError(qsTranslate('error', 'Illegal escape sequence: %1.').arg("\\u" + codePoint)); } buffer += String.fromCharCode(parseInt(codePoint, 16)); index += 4; break; default: - throw this.parseError('Illegal escape sequence: "\\' + c + '"'); + throw this.parseError(qsTranslate('error', 'Illegal escape sequence: %1.').arg('\\' + c)); } ++index; var backslash = v.indexOf('\\', index); @@ -1007,7 +1015,7 @@ TokenStream.prototype.getCoordinates = function () { TokenStream.prototype.parseError = function (msg) { var coords = this.getCoordinates(); - throw new Error('parse error [' + coords.line + ':' + coords.column + ']: ' + msg); + throw new Error(qsTranslate('error', 'Parse error [%1:%2]: %3').arg(coords.line).arg(coords.column).arg(msg)); }; function ParserState(parser, tokenStream, options) { @@ -1061,7 +1069,9 @@ ParserState.prototype.accept = function (type, value) { ParserState.prototype.expect = function (type, value) { if (!this.accept(type, value)) { var coords = this.tokens.getCoordinates(); - throw new Error('parse error [' + coords.line + ':' + coords.column + ']: Expected ' + (value || type)); + throw new Error(qsTranslate('error', 'Parse error [%1:%2]: %3') + .arg(coords.line).arg(coords.column) + .arg(qsTranslate('error', 'Expected %1').arg(qsTranslate('error',value) || type))); } }; @@ -1088,7 +1098,7 @@ ParserState.prototype.parseAtom = function (instr) { instr.push(new Instruction(IARRAY, argCount)); } } else { - throw new Error('unexpected ' + this.nextToken); + throw new Error(qsTranslate('error', 'Unexpected %1').arg(this.nextToken)); } }; @@ -1145,7 +1155,7 @@ ParserState.prototype.parseVariableAssignmentExpression = function (instr) { var lastInstrIndex = instr.length - 1; if (varName.type === IFUNCALL) { if (!this.tokens.isOperatorEnabled('()=')) { - throw new Error('function definition is not permitted'); + throw new Error(qsTranslate('error', 'Function definition is not permitted.')); } for (var i = 0, len = varName.value + 1; i < len; i++) { var index = lastInstrIndex - i; @@ -1159,7 +1169,7 @@ ParserState.prototype.parseVariableAssignmentExpression = function (instr) { continue; } if (varName.type !== IVAR && varName.type !== IMEMBER) { - throw new Error('expected variable for assignment'); + throw new Error(qsTranslate('error', 'Expected variable for assignment.')); } this.parseVariableAssignmentExpression(varValue); instr.push(new Instruction(IVARNAME, varName.value)); @@ -1323,21 +1333,21 @@ ParserState.prototype.parseMemberExpression = function (instr) { if (op.value === '.') { if (!this.allowMemberAccess) { - throw new Error('unexpected ".", member access is not permitted'); + throw new Error(qsTranslate('error', 'Unexpected ".": member access is not permitted')); } this.expect(TNAME); instr.push(new Instruction(IMEMBER, this.current.value)); } else if (op.value === '[') { if (!this.tokens.isOperatorEnabled('[')) { - throw new Error('unexpected "[]", arrays are disabled'); + throw new Error(qsTranslate('error', 'Unexpected "[]": arrays are disabled.')); } this.parseExpression(instr); this.expect(TBRACKET, ']'); instr.push(binaryInstruction('[')); } else { - throw new Error('unexpected symbol: ' + op.value); + throw new Error(qsTranslate('error', 'Unexpected symbol: %1.').arg(op.value)); } } }; @@ -1614,10 +1624,10 @@ function min(array) { function arrayMap(f, a) { if (typeof f !== 'function') { - throw new Error('First argument to map is not a function'); + throw new Error(qsTranslate('error', 'First argument to map is not a function.')); } if (!Array.isArray(a)) { - throw new Error('Second argument to map is not an array'); + throw new Error(qsTranslate('error', 'Second argument to map is not an array.')); } return a.map(function (x, i) { return f(x, i); @@ -1626,10 +1636,10 @@ function arrayMap(f, a) { function arrayFold(f, init, a) { if (typeof f !== 'function') { - throw new Error('First argument to fold is not a function'); + throw new Error(qsTranslate('error', 'First argument to fold is not a function.')); } if (!Array.isArray(a)) { - throw new Error('Second argument to fold is not an array'); + throw new Error(qsTranslate('error', 'Second argument to fold is not an array.')); } return a.reduce(function (acc, x, i) { return f(acc, x, i); @@ -1638,10 +1648,10 @@ function arrayFold(f, init, a) { function arrayFilter(f, a) { if (typeof f !== 'function') { - throw new Error('First argument to filter is not a function'); + throw new Error(qsTranslate('error', 'First argument to filter is not a function.')); } if (!Array.isArray(a)) { - throw new Error('Second argument to filter is not an array'); + throw new Error(qsTranslate('error', 'Second argument to filter is not an array.')); } return a.filter(function (x, i) { return f(x, i); @@ -1650,7 +1660,7 @@ function arrayFilter(f, a) { function stringOrArrayIndexOf(target, s) { if (!(Array.isArray(s) || typeof s === 'string')) { - throw new Error('Second argument to indexOf is not a string or array'); + throw new Error(qsTranslate('error', 'Second argument to indexOf is not a string or array.')); } return s.indexOf(target); @@ -1658,7 +1668,7 @@ function stringOrArrayIndexOf(target, s) { function arrayJoin(sep, a) { if (!Array.isArray(a)) { - throw new Error('Second argument to join is not an array'); + throw new Error(qsTranslate('error', 'Second argument to join is not an array.')); } return a.join(sep); @@ -1785,7 +1795,7 @@ class Parser { ); parserState.parseExpression(instr); - parserState.expect(TEOF, 'EOF'); + parserState.expect(TEOF, QT_TRANSLATE_NOOP('error','EOF')); return new Expression(instr, this); } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index 88ebac6..a9b008a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -47,6 +47,10 @@ class Expression { return this.requiredObjects().every(objName => objName in C.currentObjectsByName) } + undefinedVariables() { + return this.requiredObjects().filter(objName => !(objName in C.currentObjectsByName)) + } + recache() { if(this.cached) this.cachedValue = this.calc.evaluate(C.currentObjectsByName) From 6116ffe4e7370f5867e6d2f23fb8832d314edcfe Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 18:31:42 +0200 Subject: [PATCH 032/436] Removing tab switch on file open due to previous fix about first tab length. --- .../ad5001/LogarithmPlotter/LogarithmPlotter.qml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index ca1b087..7ade306 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -272,15 +272,15 @@ ApplicationWindow { history.unserialize(...data["history"]) // Refreshing sidebar - if(sidebarSelector.currentIndex == 0) { - // For some reason, if we load a file while the tab is on object, - // we get stuck in a Qt-side loop? Qt bug or side-effect here, I don't know. - sidebarSelector.currentIndex = 1 + //if(sidebarSelector.currentIndex == 0) { + // // For some reason, if we load a file while the tab is on object, + // // we get stuck in a Qt-side loop? Qt bug or side-effect here, I don't know. + // sidebarSelector.currentIndex = 1 + // objectLists.update() + // delayRefreshTimer.start() + //} else { objectLists.update() - delayRefreshTimer.start() - } else { - objectLists.update() - } + //} } else { error = qsTr("Invalid file provided.") } From fcf5ef9539e359aed58c08b56aad51bd6108c98b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 22:17:10 +0200 Subject: [PATCH 033/436] Fixing a few bugs related to dependency and text. --- .../ObjectLists/ObjectRow.qml | 20 +++++++++++++++---- .../eu/ad5001/LogarithmPlotter/js/objects.js | 2 +- .../ad5001/LogarithmPlotter/js/objs/common.js | 4 ++-- .../ad5001/LogarithmPlotter/js/objs/text.js | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 3937c4f..78d726b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -110,6 +110,7 @@ Item { MouseArea { anchors.fill: parent onClicked: { + console.log(obj.type) objEditor.obj = Objects.currentObjects[obj.type][index] objEditor.objType = obj.type objEditor.objIndex = index @@ -169,10 +170,7 @@ Item { ToolTip.text: qsTr("Delete %1 %2").arg(obj.constructor.displayType()).arg(obj.name) onClicked: { - history.addToHistory(new HistoryLib.DeleteObject( - obj.name, obj.type, obj.export() - )) - Objects.deleteObject(obj.name) + deleteRecursively(obj) changed() } } @@ -207,4 +205,18 @@ Item { changed() } } + + /*! + \qmlmethod void ObjectRow::deleteRecursively(var object) + Deletes an object and it's dependencies recursively. + */ + function deleteRecursively(object) { + console.log(object.name, object.requiredBy.length) + for(let toRemove of object.requiredBy) + deleteRecursively(toRemove) + history.addToHistory(new HistoryLib.DeleteObject( + object.name, object.type, object.export() + )) + Objects.deleteObject(object.name) + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js index 1a23f7c..ada8150 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js @@ -46,8 +46,8 @@ function deleteObject(objName) { * @param {string} objName - Current name of the object. */ let obj = currentObjectsByName[objName] - delete currentObjectsByName[objName] currentObjects[obj.type].splice(currentObjects[obj.type].indexOf(obj),1) + delete currentObjectsByName[objName] obj.delete() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 795d0a0..8968ed6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -200,7 +200,7 @@ class DrawableObject { if(properties[property] == 'Expression' && this[property] != null) { // Expressions with dependencies for(let objName of this[property].requiredObjects()) { - if(objName in C.currentObjectsByName) { + if(objName in C.currentObjectsByName && !this.requires.includes(objName)) { this.requires.push(C.currentObjectsByName[objName]) C.currentObjectsByName[objName].requiredBy.push(this) } @@ -224,7 +224,7 @@ class DrawableObject { * Callback method when the object is about to get deleted. */ delete() { - for(let toRemove of this.requiredBy) { + for(let toRemove of this.requiredBy) { // Normally, there should be none here, but better leave nothing just in case. Objects.deleteObject(toRemove.name) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index 77f5c5d..a8dcd4e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -45,7 +45,7 @@ class Text extends Common.DrawableObject { x = 1, y = 0, labelPosition = 'center', text = 'New text', disableLatex = false) { if(name == null) name = Common.getNewName('t') super(name, visible, color, labelContent) - this.type = 'Point' + this.type = 'Text' if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) this.x = x if(typeof y == 'number' || typeof y == 'string') y = new MathLib.Expression(y.toString()) From 64d1419452b85b8077ab514d987e4a1144916ad9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 22:40:49 +0200 Subject: [PATCH 034/436] Fixing bugs in recursive object deletion and dependency. --- .../qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml | 6 +++++- .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml | 3 +-- .../qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js | 4 ++-- .../qml/eu/ad5001/LogarithmPlotter/js/history/create.js | 1 + .../qml/eu/ad5001/LogarithmPlotter/js/objects.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/common.js | 2 +- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 7ade306..4d7039a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -249,7 +249,11 @@ ApplicationWindow { // Importing objects Objects.currentObjects = {} - Objects.currentObjectsByName = {} + Object.keys(Objects.currentObjectsByName).forEach(key => { + delete Objects.currentObjectsByName[key]; + // Required to keep the same reference for the copy of the object used in expression variable detection. + // Another way would be to change the reference as well, but I feel like the code would be less clean. + }) for(let objType in data['objects']) { if(Object.keys(Objects.types).indexOf(objType) > -1) { Objects.currentObjects[objType] = [] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 0d215ab..0ad35ff 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -96,7 +96,7 @@ ScrollView { posPicker: positionPicker onChanged: { - //obj = Objects.currentObjects[objType][index] + obj = Objects.currentObjects[objType][index] objectListList.update() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 78d726b..11ce7aa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -110,7 +110,6 @@ Item { MouseArea { anchors.fill: parent onClicked: { - console.log(obj.type) objEditor.obj = Objects.currentObjects[obj.type][index] objEditor.objType = obj.type objEditor.objIndex = index @@ -211,9 +210,9 @@ Item { Deletes an object and it's dependencies recursively. */ function deleteRecursively(object) { - console.log(object.name, object.requiredBy.length) for(let toRemove of object.requiredBy) deleteRecursively(toRemove) + object.requiredBy = [] history.addToHistory(new HistoryLib.DeleteObject( object.name, object.type, object.export() )) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index c615305..7ac669a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -1836,9 +1836,9 @@ var optionNameMap = { 'not': 'logical', '?': 'conditional', ':': 'conditional', - '=': 'assignment', + //'=': 'assignment', // Disable assignment '[': 'array', - '()=': 'fndef' + //'()=': 'fndef' // Diable function definition }; function getOptionName(op) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js index 00af298..7545372 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js @@ -45,6 +45,7 @@ class CreateNewObject extends C.Action { redo() { Objects.createNewRegisteredObject(this.targetType, this.targetProperties) + Objects.currentObjectsByName[this.targetName].update() } export() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js index ada8150..9f3e972 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js @@ -47,8 +47,8 @@ function deleteObject(objName) { */ let obj = currentObjectsByName[objName] currentObjects[obj.type].splice(currentObjects[obj.type].indexOf(obj),1) - delete currentObjectsByName[objName] obj.delete() + delete currentObjectsByName[objName] } function getObjectsName(objType) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 8968ed6..b966d55 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -200,7 +200,7 @@ class DrawableObject { if(properties[property] == 'Expression' && this[property] != null) { // Expressions with dependencies for(let objName of this[property].requiredObjects()) { - if(objName in C.currentObjectsByName && !this.requires.includes(objName)) { + if(objName in C.currentObjectsByName && !this.requires.includes(C.currentObjectsByName[objName])) { this.requires.push(C.currentObjectsByName[objName]) C.currentObjectsByName[objName].requiredBy.push(this) } From 32db56304bfbbfe9b61cf74282a36d4f2a0eeab0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 18 Oct 2022 23:24:58 +0200 Subject: [PATCH 035/436] Expression editor! --- .../ObjectLists/Editor/CustomPropertyList.qml | 88 +++---- .../Popup/InsertCharacter.qml | 72 ++++++ .../eu/ad5001/LogarithmPlotter/Popup/qmldir | 1 + .../Setting/ExpressionEditor.qml | 214 ++++++++++++++++++ .../LogarithmPlotter/Setting/TextSetting.qml | 54 ++--- .../eu/ad5001/LogarithmPlotter/Setting/qmldir | 2 +- 6 files changed, 345 insertions(+), 86 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 0bb35bb..42499a9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -18,10 +18,8 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 -import QtQuick.Dialogs 1.3 as D import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "../../js/objects.js" as Objects -import "../../js/objs/common.js" as ObjectsCommons import "../../js/historylib.js" as HistoryLib import "../../js/utils.js" as Utils import "../../js/mathlib.js" as MathLib @@ -46,7 +44,7 @@ Repeater { */ property var obj - readonly property var textTypes: ['Expression', 'Domain', 'string', 'number'] + readonly property var textTypes: ['Domain', 'string', 'number'] readonly property var comboBoxTypes: ['ObjectType', 'Enum'] readonly property var listTypes: ['List', 'Dict'] @@ -66,48 +64,43 @@ Repeater { } } + Component { + id: expressionEditorComponent + + // Setting for expressions + Setting.ExpressionEditor { + height: 30 + label: propertyLabel + icon: `settings/custom/${propertyIcon}.svg` + defValue: Utils.simplifyExpression(obj[propertyName].toEditableString()) + self: obj.name + onChanged: function(newExpr) { + if(obj[propertyName].toString() != newExpr.toString()) { + history.addToHistory(new HistoryLib.EditedProperty( + obj.name, objType, propertyName, + obj[propertyName], newExpr + )) + obj[propertyName] = newExpr + root.changed() + } + } + } + } + + Component { id: textEditorComponent - // Setting for text & number settings as well as domains & expressions + // Setting for text & number settings as well as domains Setting.TextSetting { height: 30 label: propertyLabel icon: `settings/custom/${propertyIcon}.svg` isDouble: propertyType == 'number' - defValue: { - switch(propertyType) { - case 'Expression': - return Utils.simplifyExpression(obj[propertyName].toEditableString()) - break - case 'string': - return obj[propertyName] - break - case 'Domain': - case 'number': - default: - return obj[propertyName].toString() - } - } + defValue: obj[propertyName] == null ? '' : obj[propertyName].toString() onChanged: function(newValue) { try { var newValueParsed = { - 'Expression': () => { - let expr = new MathLib.Expression(newValue) - // Check if the expression is valid, throws error otherwise. - if(!expr.allRequirementsFullfilled()) { - let undefVars = expr.undefinedVariables() - console.log(JSON.stringify(undefVars), undefVars.join(', ')) - if(undefVars.length > 1) - throw new Error(qsTranslate('error', 'No object found with names %1.').arg(undefVars.join(', '))) - else - throw new Error(qsTranslate('error', 'No object found with name %1.').arg(undefVars.join(', '))) - } - if(expr.requiredObjects().includes(obj.name)) - throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) - // TODO: Check for recursive dependencies. - return expr - }, 'Domain': () => MathLib.parseDomain(newValue), 'string': () => newValue, 'number': () => parseFloat(newValue) @@ -129,15 +122,15 @@ Repeater { } - D.MessageDialog { - id: parsingErrorDialog - title: qsTr("LogarithmPlotter - Parsing error") - text: "" - function showDialog(propName, propValue, error) { - text = qsTr("Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3").arg(propName).arg(error).arg(propValue) - open() - } - } + // D.MessageDialog { + // id: parsingErrorDialog + // title: qsTranslate("expression", "LogarithmPlotter - Parsing error") + // text: "" + // function showDialog(propName, propValue, error) { + // text = qsTranslate("error", "Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3").arg(propName).arg(error).arg(propValue) + // open() + // } + // } } } @@ -150,7 +143,12 @@ Repeater { text: propertyLabel //icon: `settings/custom/${propertyIcon}.svg` - checked: obj[propertyName] + checked: { + //if(obj[propertyName] == null) { + // return false + //} + return obj[propertyName] + } onClicked: { history.addToHistory(new HistoryLib.EditedProperty( obj.name, objType, propertyName, @@ -269,6 +267,8 @@ Repeater { return commentComponent else if(propertyType == 'boolean') return checkboxComponent + else if(propertyType == 'Expression') + return expressionEditorComponent else if(paramTypeIn(propertyType, textTypes)) return textEditorComponent else if(paramTypeIn(propertyType, comboBoxTypes)) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml new file mode 100644 index 0000000..bbeb3e0 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -0,0 +1,72 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick.Controls 2.12 +import QtQuick 2.12 + +/*! + \qmltype InsertCharacter + \inqmlmodule eu.ad5001.LogarithmPlotter.Setting + \brief Popup to insert special character. + + \sa TextSetting, ExpressionEditor +*/ +Popup { + id: insertPopup + + signal selected(string character) + + width: 280 + height: insertGrid.insertChars.length/insertGrid.columns*(width/insertGrid.columns) + modal: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + + Grid { + id: insertGrid + width: parent.width + columns: 7 + + property var insertChars: [ + "α","β","γ","δ","ε","ζ","η", + "π","θ","κ","λ","μ","ξ","ρ", + "ς","σ","τ","φ","χ","ψ","ω", + "Γ","Δ","Θ","Λ","Ξ","Π","Σ", + "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", + "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", + "ₜ","¹","²","³","⁴","⁵","⁶", + "⁷","⁸","⁹","⁰","₁","₂","₃", + "₄","₅","₆","₇","₈","₉","₀" + ] + Repeater { + model: parent.insertChars.length + + Button { + id: insertBtn + width: insertGrid.width/insertGrid.columns + height: width + text: insertGrid.insertChars[modelData] + flat: text == " " + font.pixelSize: 18 + + onClicked: { + selected(text) + } + } + } + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir index 3f71a18..fb7800e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir @@ -6,3 +6,4 @@ FileDialog 1.0 FileDialog.qml GreetScreen 1.0 GreetScreen.qml Changelog 1.0 Changelog.qml ThanksTo 1.0 ThanksTo.qml +InsertCharacter 1.0 InsertCharacter.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml new file mode 100644 index 0000000..313b071 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -0,0 +1,214 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick.Controls 2.12 +import QtQuick 2.12 +import QtQuick.Dialogs 1.3 as D +import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup +import "../js/mathlib.js" as MathLib + + +/*! + \qmltype ExpressionEditor + \inqmlmodule eu.ad5001.LogarithmPlotter.Setting + \brief Setting to edit strings and numbers. + + \sa EditorDialog, Settings, Icon +*/ +Item { + id: control + height: 30 + + /*! + \qmlsignal ExpressionEditor::changed(var newValue) + + Emitted when the value of the expression has been changed. + The corresponding handler is \c onChanged. + */ + signal changed(var newValue) + + /*! + \qmlproperty string ExpressionEditor::defValue + Default editable expression value of the editor. + */ + property string defValue + /*! + \qmlproperty string ExpressionEditor::value + Value of the editor. + */ + property alias value: editor.text + /*! + \qmlproperty string ExpressionEditor::self + Object or context of the expression to be edited. + Used to prevent circular dependency. + */ + property string self: "" + /*! + \qmlproperty string ExpressionEditor::placeholderText + Value of the editor. + */ + property alias placeholderText: editor.placeholderText + /*! + \qmlproperty string ExpressionEditor::label + Label of the editor. + */ + property string label + /*! + \qmlproperty string ExpressionEditor::icon + Icon path of the editor. + */ + property string icon: "" + + /*! + \qmlproperty string ExpressionEditor::openAndCloseMatches + Characters that when pressed, should be immediately followed up by their closing character. + */ + readonly property var openAndCloseMatches: { + "(": ")", + "[": "]", + "'": "'", + '"': '"' + } + + Icon { + id: iconLabel + anchors.top: parent.top + anchors.topMargin: icon == "" ? 0 : 3 + source: control.visible && icon != "" ? "../icons/" + control.icon : "" + width: height + height: icon == "" || !visible ? 0 : 24 + color: sysPalette.windowText + } + + Label { + id: labelItem + anchors.left: iconLabel.right + anchors.leftMargin: icon == "" ? 0 : 5 + height: parent.height + anchors.top: parent.top + verticalAlignment: TextInput.AlignVCenter + //color: sysPalette.windowText + text: visible ? qsTranslate("control", "%1: ").arg(control.label) : "" + visible: control.label != "" + } + + D.MessageDialog { + id: parsingErrorDialog + title: qsTranslate("expression", "LogarithmPlotter - Parsing error") + text: "" + function showDialog(propName, propValue, error) { + text = qsTranslate("expression", "Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3").arg(propName).arg(error).arg(propValue) + open() + } + } + + TextField { + id: editor + anchors.top: parent.top + anchors.left: labelItem.right + anchors.leftMargin: 5 + width: control.width - (labelItem.visible ? labelItem.width + 5 : 0) - iconLabel.width - 5 + height: parent.height + verticalAlignment: TextInput.AlignVCenter + horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter + text: control.defValue + color: sysPalette.windowText + focus: true + selectByMouse: true + + Keys.priority: Keys.BeforeItem // Required for knowing which key the user presses. + + onEditingFinished: { + if(insertButton.focus || insertPopup.focus) return + let value = text + if(value != "" && value.toString() != defValue) { + let expr = parse(value) + if(expr != null) { + control.changed(expr) + defValue = expr.toEditableString() + } + } + } + + Keys.onPressed: function(event) { + if(event.text in openAndCloseMatches) { + let start = selectionStart + insert(selectionStart, event.text) + insert(selectionEnd, openAndCloseMatches[event.text]) + cursorPosition = start+1 + event.accepted = true + } + } + } + + Button { + id: insertButton + text: "α" + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.verticalCenter: parent.verticalCenter + width: 20 + height: width + onClicked: { + insertPopup.open() + insertPopup.focus = true + } + } + + Popup.InsertCharacter { + id: insertPopup + + x: Math.round((parent.width - width) / 2) + y: Math.round((parent.height - height) / 2) + + onSelected: function(c) { + editor.insert(editor.cursorPosition, c) + insertPopup.close() + editor.focus = true + } + } + + /*! + \qmlmethod var ExpressionEditor::parse(string newExpression) + Parses the \c newExpression as an expression, checks for errors, shows them if any. + Returns the parsed expression if possible, null otherwise.. + */ + function parse(newExpression) { + let expr = null + try { + expr = new MathLib.Expression(value.toString()) + // Check if the expression is valid, throws error otherwise. + if(!expr.allRequirementsFullfilled()) { + let undefVars = expr.undefinedVariables() + console.log(JSON.stringify(undefVars), undefVars.join(', ')) + if(undefVars.length > 1) + throw new Error(qsTranslate('error', 'No object found with names %1.').arg(undefVars.join(', '))) + else + throw new Error(qsTranslate('error', 'No object found with name %1.').arg(undefVars.join(', '))) + } + if(expr.requiredObjects().includes(control.self)) + throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) + // TODO: Check for recursive dependencies. + } catch(e) { + // Error in expression + parsingErrorDialog.showDialog(propertyName, newExpression, e.message) + } + return expr + } +} + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index e361250..a823645 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -18,6 +18,7 @@ import QtQuick.Controls 2.12 import QtQuick 2.12 +import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup /*! \qmltype TextSetting @@ -119,6 +120,7 @@ Item { text: control.defValue selectByMouse: true onEditingFinished: { + if(insertButton.focus || insertPopup.focus) return var value = text if(control.isInt) value = Math.max(control.min,parseInt(value).toString()=="NaN"?control.min:parseInt(value)) if(control.isDouble) value = Math.max(control.min,parseFloat(value).toString()=="NaN"?control.min:parseFloat(value)) @@ -130,6 +132,7 @@ Item { } Button { + id: insertButton text: "α" anchors.right: parent.right anchors.rightMargin: 5 @@ -137,53 +140,22 @@ Item { width: 20 height: width visible: !isInt && !isDouble - onClicked: insertPopup.open() + onClicked: { + insertPopup.open() + insertPopup.focus = true + } } - Popup { + Popup.InsertCharacter { id: insertPopup + x: Math.round((parent.width - width) / 2) y: Math.round((parent.height - height) / 2) - width: 280 - height: insertGrid.insertChars.length/insertGrid.columns*(width/insertGrid.columns) - modal: true - focus: true - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent - Grid { - id: insertGrid - width: parent.width - columns: 7 - - property var insertChars: [ - "α","β","γ","δ","ε","ζ","η", - "π","θ","κ","λ","μ","ξ","ρ", - "ς","σ","τ","φ","χ","ψ","ω", - "Γ","Δ","Θ","Λ","Ξ","Π","Σ", - "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", - "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", - "ₜ","¹","²","³","⁴","⁵","⁶", - "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀" - ] - Repeater { - model: parent.insertChars.length - - Button { - id: insertBtn - width: insertGrid.width/insertGrid.columns - height: width - text: insertGrid.insertChars[modelData] - flat: text == " " - font.pixelSize: 18 - - onClicked: { - input.insert(input.cursorPosition, insertGrid.insertChars[modelData]) - insertPopup.close() - input.focus = true - } - } - } + onSelected: function(c) { + input.insert(input.cursorPosition, c) + insertPopup.close() + input.focus = true } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir index 22ad816..d6e55e5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir @@ -4,4 +4,4 @@ ComboBoxSetting 1.0 ComboBoxSetting.qml Icon 1.0 Icon.qml ListSetting 1.0 ListSetting.qml TextSetting 1.0 TextSetting.qml - +ExpressionEditor 1.0 ExpressionEditor.qml From 4564d5446f123829a358fd67029e997f38d220ff Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 01:16:54 +0200 Subject: [PATCH 036/436] Syntax coloration first attempt! Currently, when there are two many styles, the text is *slightly* offset from the normal one. --- .../Setting/ExpressionEditor.qml | 75 ++++++++++++++++++- .../LogarithmPlotter/js/parsing/builder.js | 4 +- .../LogarithmPlotter/js/parsing/common.js | 2 +- .../LogarithmPlotter/js/parsing/tokenizer.js | 73 ++++++++++++------ .../eu/ad5001/LogarithmPlotter/js/utils.js | 4 + 5 files changed, 131 insertions(+), 27 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 313b071..11a191a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -21,6 +21,8 @@ import QtQuick 2.12 import QtQuick.Dialogs 1.3 as D import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup import "../js/mathlib.js" as MathLib +import "../js/utils.js" as Utils +import "../js/parsing/parsing.js" as Parsing /*! @@ -77,6 +79,7 @@ Item { /*! \qmlproperty string ExpressionEditor::openAndCloseMatches Characters that when pressed, should be immediately followed up by their closing character. + TODO: Make it configurable. */ readonly property var openAndCloseMatches: { "(": ")", @@ -85,6 +88,21 @@ Item { '"': '"' } + /*! + \qmlproperty string ExpressionEditor::colorScheme + Color scheme of the editor, currently based on Breeze Light. + TODO: Make it configurable. + */ + readonly property var colorScheme: { + 'NORMAL': "#1F1C1B", + 'VARIABLE': "#0057AE", + 'CONSTANT': "#5E2F00", + 'FUNCTION': "#644A9B", + 'OPERATOR': "#A44EA4", + 'STRING': "#9C0E0E", + 'NUMBER': "#805C00" + } + Icon { id: iconLabel anchors.top: parent.top @@ -117,6 +135,7 @@ Item { } } + TextField { id: editor anchors.top: parent.top @@ -126,8 +145,9 @@ Item { height: parent.height verticalAlignment: TextInput.AlignVCenter horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter + font.pixelSize: 14 text: control.defValue - color: sysPalette.windowText + color: "transparent"//sysPalette.windowText focus: true selectByMouse: true @@ -154,6 +174,18 @@ Item { event.accepted = true } } + + Text { + id: colorizedEditor + anchors.fill: editor + verticalAlignment: TextInput.AlignVCenter + horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter + textFormat: Text.StyledText + text: colorize(editor.text) + color: sysPalette.windowText + font.pixelSize: parent.font.pixelSize + //opacity: editor.activeFocus ? 0 : 1 + } } Button { @@ -210,5 +242,46 @@ Item { } return expr } + + /*! + \qmlmethod var ExpressionEditor::colorize(string expressionText) + Creates an HTML colorized string of the incomplete \c expressionText. + Returns the colorized and escaped expression if possible, null otherwise.. + */ + function colorize(text) { + let tokenizer = new Parsing.Tokenizer(new Parsing.Input(text), true, false) + let parsedText = "" + let token + console.log("Parsing text:", parsedText) + while((token = tokenizer.next()) != null) { + switch(token.type) { + case Parsing.TokenType.VARIABLE: + parsedText += `${token.value}` + break; + case Parsing.TokenType.CONSTANT: + parsedText += `${token.value}` + break; + case Parsing.TokenType.FUNCTION: + parsedText += `${token.value}` + break; + case Parsing.TokenType.OPERATOR: + parsedText += `${Utils.escapeHTML(token.value)}` + break; + case Parsing.TokenType.NUMBER: + parsedText += `${Utils.escapeHTML(token.value)}` + break; + case Parsing.TokenType.STRING: + parsedText += `${token.limitator}${Utils.escapeHTML(token.value)}${token.limitator}` + break; + case Parsing.TokenType.WHITESPACE: + case Parsing.TokenType.PUNCT: + default: + parsedText += Utils.escapeHTML(token.value).replace(/ /g, ' ') + break; + } + } + console.log("Parsed text:", parsedText) + return parsedText + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js index c431fab..b81b6e1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js @@ -18,8 +18,8 @@ .pragma library -import "ast.js" as AST -import "tokenizer.js" as TK +.import "ast.js" as AST +.import "tokenizer.js" as TK class ExpressionBuilder { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js index bda1b2c..05960fd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js @@ -33,7 +33,7 @@ class InputExpression { } skip(char) { - if(!atEnd() && peek() == char) { + if(!this.atEnd() && this.peek() == char) { this.position++; } else { this.raise("Unexpected character " + peek() + ". Expected character " + char); diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js index d600f5b..6d8e20b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js @@ -22,20 +22,22 @@ const WHITESPACES = " \t\n\r" const STRING_LIMITORS = '"\'`'; -const OPERATORS = "+-*/^%"; -const PUNCTUTATION = "()[]{},"; +const OPERATORS = "+-*/^%?:=!><"; +const PUNCTUTATION = "()[]{},."; const NUMBER_CHARS = "0123456789." const IDENTIFIER_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_₀₁₂₃₄₅₆₇₈₉αβγδεζηθκλμξρςστφχψωₐₑₒₓₔₕₖₗₘₙₚₛₜ" -enum TokenType { +var TokenType = { // Expression type - VARIABLE, - CONSTANT, - FUNCTION, - OPERATOR, - PUNCT, - NUMBER, - STRING + "WHITESPACE": "WHITESPACE", + "VARIABLE": "VARIABLE", + "CONSTANT": "CONSTANT", + "FUNCTION": "FUNCTION", + "OPERATOR": "OPERATOR", + "PUNCT": "PUNCT", + "NUMBER": "NUMBER", + "STRING": "STRING", + "UNKNOWN": "UNKNOWN" } class Token { @@ -46,9 +48,11 @@ class Token { } class ExpressionTokenizer { - constructor(input) { + constructor(input, tokenizeWhitespaces = false, errorOnUnknown = true) { this.input = input; this.currentToken = null; + this.tokenizeWhitespaces = tokenizeWhitespaces + this.errorOnUnknown = errorOnUnknown } skipWhitespaces() { @@ -56,6 +60,14 @@ class ExpressionTokenizer { this.input.next(); } + readWhitespaces() { + let included = ""; + while(!this.input.atEnd() && WHITESPACES.includes(this.input.peek())) { + included += this.input.next(); + } + return new Token(TokenType.WHITESPACE, included) + } + readString() { let delimitation = this.input.peek(); if(STRING_LIMITORS.includes(delimitation)) { @@ -68,7 +80,9 @@ class ExpressionTokenizer { included += this.input.next(); } this.input.skip(delimitation) - return new Token(TokenType.STRING, included); + let token = new Token(TokenType.STRING, included) + token.limitator = delimitation + return token } else { this.input.raise("Unexpected " + delimitation + ". Expected string delimitator") } @@ -84,12 +98,20 @@ class ExpressionTokenizer { } included += this.input.next(); } + return new Token(TokenType.NUMBER, included) + } + + readOperator() { + let included = ""; + while(!this.input.atEnd() && OPERATORS.includes(this.input.peek())) { + included += this.input.next(); + } + return new Token(TokenType.OPERATOR, included) } readIdentifier() { let identifier = ""; - let hasDot = false; - while(!this.input.atEnd() && IDENTIFIER_CHARS.includes(this.input.peek())) { + while(!this.input.atEnd() && IDENTIFIER_CHARS.includes(this.input.peek().toLowerCase())) { identifier += this.input.next(); } if(Reference.CONSTANTS_LIST.includes(identifier.toLowerCase())) { @@ -102,16 +124,21 @@ class ExpressionTokenizer { } readNextToken() { - this.skipWhitespaces() - if(input.atEnd()) return null; - let c = input.peek(); + if(!this.tokenizeWhitespaces) + this.skipWhitespaces() + if(this.input.atEnd()) return null; + let c = this.input.peek(); + if(this.tokenizeWhitespaces && WHITESPACES.includes(c)) return this.readWhitespaces(); if(STRING_LIMITORS.includes(c)) return this.readString(); if(NUMBER_CHARS.includes(c)) return this.readNumber(); - if(IDENTIFIER_CHARS.includes(c)) return this.readIdentifier(); + if(IDENTIFIER_CHARS.includes(c.toLowerCase())) return this.readIdentifier(); + if(OPERATORS.includes(c)) return this.readOperator(); if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, c); - if(OPERATORS.includes(c)) return new Token(TokenType.OPERATOR, c); - if(PUNCTUTATION.includes(c)) return new Token(TokenType.PUNCT, c); - this.input.throw("Unknown token character " + c) + if(PUNCTUTATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next()); + if(this.errorOnUnknown) + this.input.throw("Unknown token character " + c) + else + return new Token(TokenType.UNKNOWN, this.input.next()); } peek() { @@ -134,8 +161,8 @@ class ExpressionTokenizer { } skip(type) { - Token next = Next(); + let next = this.next(); if(next.type != type) - input.raise("Unexpected token " + next.type.oLowerCase() + ' "' + next.value + '". Expected ' + type.toLowerCase()); + input.raise("Unexpected token " + next.type.toLowerCase() + ' "' + next.value + '". Expected ' + type.toLowerCase()); } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index a383846..ed3a8f5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -347,3 +347,7 @@ function getRandomColor() { } return color; } + +function escapeHTML(str) { + return str.replace(/&/g,'&').replace(//g,'>') ; +} From 971a9d10d2147c88fc5e403cda51539e4762cdc3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 01:18:25 +0200 Subject: [PATCH 037/436] Reverting not swapping the sidebar at load. As the bug is *still* very much present. Notably when you load a graph from command line arguments. --- .../ad5001/LogarithmPlotter/LogarithmPlotter.qml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 4d7039a..445c03c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -276,15 +276,15 @@ ApplicationWindow { history.unserialize(...data["history"]) // Refreshing sidebar - //if(sidebarSelector.currentIndex == 0) { - // // For some reason, if we load a file while the tab is on object, - // // we get stuck in a Qt-side loop? Qt bug or side-effect here, I don't know. - // sidebarSelector.currentIndex = 1 - // objectLists.update() - // delayRefreshTimer.start() - //} else { + if(sidebarSelector.currentIndex == 0) { + // For some reason, if we load a file while the tab is on object, + // we get stuck in a Qt-side loop? Qt bug or side-effect here, I don't know. + sidebarSelector.currentIndex = 1 + objectLists.update() + delayRefreshTimer.start() + } else { objectLists.update() - //} + } } else { error = qsTr("Invalid file provided.") } From dc532fcd19eb6d654e0817564d5f8676c15c19a0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 01:19:52 +0200 Subject: [PATCH 038/436] Forgot to add the parsing javascript module. --- .../LogarithmPlotter/js/parsing/README.md | 5 ++++ .../LogarithmPlotter/js/parsing/parsing.js | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md new file mode 100644 index 0000000..a0ff7e7 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md @@ -0,0 +1,5 @@ +# General information + +Here lies the potential new, abandoned, cleaner implementation of the parsing system that was supposed to replace expr-eval.js, but never came to be because it's unfinished. If somebody has the will to finish this, you're welcome to try, as I won't. + +Currently, the tokenizer is complete in use to provide tokens for the syntax highlighting. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js new file mode 100644 index 0000000..c1e1aaf --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js @@ -0,0 +1,28 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +.pragma library + +.import "reference.js" as Reference +.import "tokenizer.js" as TK +.import "common.js" as Common + +var Input = Common.InputExpression +var TokenType = TK.TokenType +var Token = TK.Token +var Tokenizer = TK.ExpressionTokenizer From b519e3401617650ce5889ff074c0dec23108a75e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 01:49:30 +0200 Subject: [PATCH 039/436] Fixed bugs. 1. X Cursors pointing to an object when LaTeX is enabled make LogarithmPlotter crash due to invalid LaTeX. 2. Invalid class-property types are now directly generated from the static instance. 3. Sequences didn't include sequence value properly anymore. --- .../eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 2 -- .../qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js | 3 ++- .../qml/eu/ad5001/LogarithmPlotter/js/objs/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/function.js | 1 - .../qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js | 1 - .../qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js | 1 - .../qml/eu/ad5001/LogarithmPlotter/js/objs/point.js | 1 - .../qml/eu/ad5001/LogarithmPlotter/js/objs/text.js | 1 - .../qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js | 4 ++-- 9 files changed, 5 insertions(+), 11 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 11a191a..45c5e0a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -252,7 +252,6 @@ Item { let tokenizer = new Parsing.Tokenizer(new Parsing.Input(text), true, false) let parsedText = "" let token - console.log("Parsing text:", parsedText) while((token = tokenizer.next()) != null) { switch(token.type) { case Parsing.TokenType.VARIABLE: @@ -280,7 +279,6 @@ Item { break; } } - console.log("Parsed text:", parsedText) return parsedText } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index ddfe4e0..0c43b30 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -66,9 +66,10 @@ class Sequence extends Expr.Expression { var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) var expr = C.parser.parse(str).simplify() C.currentVars = Object.assign( - {'n': n-this.valuePlus, [this.name]: this.calcValues}, // Just in case, add n (for custom functions) + {'n': n-this.valuePlus}, // Just in case, add n (for custom functions) C.currentObjectsByName ) + C.currentVars[this.name] = this.calcValues this.calcValues[n] = expr.evaluate(C.currentVars) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index b966d55..6c15ce5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -112,7 +112,7 @@ class DrawableObject { */ constructor(name, visible = true, color = null, labelContent = 'name + value') { if(color == null) color = Utils.getRandomColor() - this.type = 'Unknown' + this.type = this.constructor.type() this.name = name this.visible = visible this.color = color diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index 44dc1f4..746d880 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -54,7 +54,6 @@ class Function extends Common.ExecutableObject { drawPoints = true, drawDashedLines = true) { if(name == null) name = Common.getNewName('fghjqlmnopqrstuvwabcde') super(name, visible, color, labelContent) - this.type = 'Function' if(typeof expression == 'number' || typeof expression == 'string') expression = new MathLib.Expression(expression.toString()) this.expression = expression if(typeof definitionDomain == 'string') definitionDomain = MathLib.parseDomain(definitionDomain) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index 265c9e9..72d583f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -46,7 +46,6 @@ class GainBode extends Common.ExecutableObject { if(name == null) name = Common.getNewName('G') if(name == 'G') name = 'G₀' // G is reserved for sum of BODE magnitudes (Somme gains Bode). super(name, visible, color, labelContent) - this.type = 'Gain Bode' if(typeof om_0 == "string") { // Point name or create one om_0 = Objects.currentObjectsByName[om_0] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index 5cbd4a9..f8d2aaf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -43,7 +43,6 @@ class PhaseBode extends Common.ExecutableObject { if(name == null) name = Common.getNewName('φ') if(name == 'φ') name = 'φ₀' // φ is reserved for sum of BODE phases (Somme phases Bode). super(name, visible, color, labelContent) - this.type = 'Phase Bode' if(typeof phase == 'number' || typeof phase == 'string') phase = new MathLib.Expression(phase.toString()) this.phase = phase if(typeof om_0 == "string") { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js index 66ba301..1f35192 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js @@ -40,7 +40,6 @@ class Point extends Common.DrawableObject { x = 1, y = 0, labelPosition = 'above', pointStyle = '●') { if(name == null) name = Common.getNewName('ABCDEFJKLMNOPQRSTUVW') super(name, visible, color, labelContent) - this.type = 'Point' if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) this.x = x if(typeof y == 'number' || typeof y == 'string') y = new MathLib.Expression(y.toString()) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index a8dcd4e..5d98e4e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -45,7 +45,6 @@ class Text extends Common.DrawableObject { x = 1, y = 0, labelPosition = 'center', text = 'New text', disableLatex = false) { if(name == null) name = Common.getNewName('t') super(name, visible, color, labelContent) - this.type = 'Text' if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) this.x = x if(typeof y == 'number' || typeof y == 'string') y = new MathLib.Expression(y.toString()) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js index 0199b6a..4d6eb60 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js @@ -49,7 +49,6 @@ class XCursor extends Common.DrawableObject { rounding = 3, displayStyle = '— — — — — — —', targetValuePosition = 'Next to target') { if(name == null) name = Common.getNewName('X') super(name, visible, color, labelContent) - this.type = 'X Cursor' this.approximate = approximate this.rounding = rounding if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) @@ -78,7 +77,8 @@ class XCursor extends Common.DrawableObject { if(this.targetElement == null) return `${Latex.variable(this.name)} = ${this.x.latexMarkup}` return `\\begin{array}{l} ${Latex.variable(this.name)} = ${this.x.latexMarkup} \\\\ - ${this.getTargetValueLatexLabel()}` + ${this.getTargetValueLatexLabel()} + \\end{array}` } getTargetValueLabel() { From e7ba1d9ff56c748b717294426950e349bbc58e1f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 01:53:53 +0200 Subject: [PATCH 040/436] Disabling font properties to reactivate native OS font size. --- .../eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 45c5e0a..5c43350 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -145,7 +145,7 @@ Item { height: parent.height verticalAlignment: TextInput.AlignVCenter horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter - font.pixelSize: 14 + //font.pixelSize: 14 text: control.defValue color: "transparent"//sysPalette.windowText focus: true @@ -183,7 +183,7 @@ Item { textFormat: Text.StyledText text: colorize(editor.text) color: sysPalette.windowText - font.pixelSize: parent.font.pixelSize + //font.pixelSize: parent.font.pixelSize //opacity: editor.activeFocus ? 0 : 1 } } From 97338506a4f71d900454c3f52c41729bbd0d7f8c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 02:00:22 +0200 Subject: [PATCH 041/436] Adding new translation strings (errors with syntax) --- LogarithmPlotter/i18n/lp_de.ts | 337 ++++++++++++++++++++++----- LogarithmPlotter/i18n/lp_en.ts | 337 ++++++++++++++++++++++----- LogarithmPlotter/i18n/lp_es.ts | 274 ++++++++++++++++++---- LogarithmPlotter/i18n/lp_fr.ts | 337 ++++++++++++++++++++++----- LogarithmPlotter/i18n/lp_hu.ts | 337 ++++++++++++++++++++++----- LogarithmPlotter/i18n/lp_nb_NO.ts | 335 +++++++++++++++++++++----- LogarithmPlotter/i18n/lp_template.ts | 272 +++++++++++++++++---- 7 files changed, 1858 insertions(+), 371 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 74ddf5c..9a88e3a 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -166,43 +166,87 @@ Schließen + + CustomPropertyList + + + + + Create new %1 + + Neues %1objekt erstellen + + + + Dialog + + + Edit properties of %1 %2 + Eigenschaften von %1 %2 bearbeiten + + + + LogarithmPlotter - Invalid object name + + + + + An object with the name '%1' already exists. + + + + + Name + Name + + + + Label content + Etikett + + + + null + leer + + + + name + Name + + + + name + value + Name + Wert + + EditorDialog - Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten - Name - Name + Name - Label content - Etikett + Etikett - null - leer + leer - name - Name + Name - name + value - Name + Wert + Name + Wert - - + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen @@ -327,37 +371,37 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not save file: Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -383,29 +427,52 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Alle %1 anzeigen - Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 - Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 - Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen - Delete %1 %2 - %1 %2 löschen + %1 %2 löschen - Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen + + + + ObjectRow + + + Hide %1 %2 + Ausblenden %1 %2 + + + + Show %1 %2 + Anzeigen %1 %2 + + + + Set %1 %2 position + Position von %1 %2 einstellen + + + + Delete %1 %2 + %1 %2 löschen + + + + Pick new color for %1 %2 + Neue Farbe für %1 %2 auswählen @@ -647,7 +714,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) - + Note: Specify the probability for each value. Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. @@ -657,7 +724,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… - + If you have latex enabled, you can use use latex markup in between $$ to create equations. Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -667,8 +734,9 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" + - + %1: %1: @@ -676,8 +744,8 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create - - + + New %1 %2 created. Neu %1 %2 erstellt. @@ -694,16 +762,175 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 von %2 %3 wurde von "%4" auf "%5" geändert. - + %1 of %2 changed from %3 to %4. %1 von %2 wurde von %3 auf %4 geändert. + + error + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + + + + + Parse error [%1:%2]: %3 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Function definition is not permitted. + + + + + Expected variable for assignment. + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + First argument to map is not a function. + + + + + Second argument to map is not an array. + + + + + First argument to fold is not a function. + + + + + Second argument to fold is not an array. + + + + + First argument to filter is not a function. + + + + + Second argument to filter is not an array. + + + + + Second argument to indexOf is not a string or array. + + + + + Second argument to join is not an array. + + + + + EOF + + + + + No object found with names %1. + + + + + No object found with name %1. + + + + + Object cannot be dependent on itself. + + + + + expression + + + LogarithmPlotter - Parsing error + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + function @@ -730,14 +957,14 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Bode-Magnituden - - + + low-pass Tiefpass - - + + high-pass Hochpass @@ -813,8 +1040,8 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde name - - + + %1 %2 renamed to %3. %1 %2 umbenannt in %3. @@ -982,11 +1209,11 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde - + - - + + labelPosition Position des Etiketts @@ -1000,10 +1227,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde - + - + labelX X-Position des Etiketts @@ -1052,14 +1279,14 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde - + x X - + y Y @@ -1069,17 +1296,17 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Punkt-Stil - + probabilities Wahrscheinlichkeiten - + text Inhalt - + disableLatex LaTeX-Rendering für diesen Text deaktivieren diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index e49fa7b..a29b1d9 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -166,43 +166,87 @@ Done + + CustomPropertyList + + + + + Create new %1 + + Create new %1 + + + + Dialog + + + Edit properties of %1 %2 + Edit properties of %1 %2 + + + + LogarithmPlotter - Invalid object name + + + + + An object with the name '%1' already exists. + + + + + Name + Name + + + + Label content + Label content + + + + null + null + + + + name + name + + + + name + value + name + value + + EditorDialog - Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 - Name - Name + Name - Label content - Label content + Label content - null - null + null - name - name + name - name + value - name + value + name + value - - + Create new %1 - + Create new %1 + + Create new %1 @@ -327,37 +371,37 @@ These settings can be changed at any time from the "Settings" menu.Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not save file: Could not save file: - + Loaded file '%1'. Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -383,29 +427,52 @@ These settings can be changed at any time from the "Settings" menu.Show all %1 - Hide %1 %2 - Hide %1 %2 + Hide %1 %2 - Show %1 %2 - Show %1 %2 + Show %1 %2 - Set %1 %2 position - Set %1 %2 position + Set %1 %2 position - Delete %1 %2 - Delete %1 %2 + Delete %1 %2 - Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 + + + + ObjectRow + + + Hide %1 %2 + Hide %1 %2 + + + + Show %1 %2 + Show %1 %2 + + + + Set %1 %2 position + Set %1 %2 position + + + + Delete %1 %2 + Delete %1 %2 + + + + Pick new color for %1 %2 + Pick new color for %1 %2 @@ -647,7 +714,7 @@ These settings can be changed at any time from the "Settings" menu.The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) - + Note: Specify the probability for each value. Note: Specify the probability for each value. @@ -657,7 +724,7 @@ These settings can be changed at any time from the "Settings" menu.Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… - + If you have latex enabled, you can use use latex markup in between $$ to create equations. If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -667,8 +734,9 @@ These settings can be changed at any time from the "Settings" menu. + - + %1: %1: @@ -676,8 +744,8 @@ These settings can be changed at any time from the "Settings" menu. create - - + + New %1 %2 created. New %1 %2 created. @@ -694,16 +762,175 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. %1 of %2 changed from %3 to %4. + + error + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + + + + + Parse error [%1:%2]: %3 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Function definition is not permitted. + + + + + Expected variable for assignment. + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + First argument to map is not a function. + + + + + Second argument to map is not an array. + + + + + First argument to fold is not a function. + + + + + Second argument to fold is not an array. + + + + + First argument to filter is not a function. + + + + + Second argument to filter is not an array. + + + + + Second argument to indexOf is not a string or array. + + + + + Second argument to join is not an array. + + + + + EOF + + + + + No object found with names %1. + + + + + No object found with name %1. + + + + + Object cannot be dependent on itself. + + + + + expression + + + LogarithmPlotter - Parsing error + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + function @@ -730,14 +957,14 @@ These settings can be changed at any time from the "Settings" menu.Bode Magnitudes - - + + low-pass low-pass - - + + high-pass high-pass @@ -813,8 +1040,8 @@ Please make sure your LaTeX installation is correct and report a bug if so. name - - + + %1 %2 renamed to %3. %1 %2 renamed to %3. @@ -982,11 +1209,11 @@ Please make sure your LaTeX installation is correct and report a bug if so. - + - - + + labelPosition Label position @@ -1000,10 +1227,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. - + - + labelX Label's X position @@ -1052,14 +1279,14 @@ Please make sure your LaTeX installation is correct and report a bug if so. - + x X - + y Y @@ -1069,17 +1296,17 @@ Please make sure your LaTeX installation is correct and report a bug if so.Point style - + probabilities Probabilities list - + text Content - + disableLatex Disable LaTeX rendering for this text diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index b8d06f2..0842196 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -167,43 +167,56 @@ - EditorDialog + CustomPropertyList - + + + + Create new %1 + + + + + Dialog + + Edit properties of %1 %2 - + + LogarithmPlotter - Invalid object name + + + + + An object with the name '%1' already exists. + + + + Name - + Label content - + null - + name - + name + value - - - - + Create new %1 - - FileDialog @@ -249,7 +262,7 @@ These settings can be changed at any time from the "Settings" menu. Enable LaTeX rendering - + Activar el renderizado de LaTeX @@ -326,37 +339,37 @@ These settings can be changed at any time from the "Settings" menu. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -381,28 +394,31 @@ These settings can be changed at any time from the "Settings" menu.Show all %1 + + + ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -646,7 +662,7 @@ These settings can be changed at any time from the "Settings" menu. - + Note: Specify the probability for each value. @@ -656,7 +672,7 @@ These settings can be changed at any time from the "Settings" menu. - + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -666,8 +682,9 @@ These settings can be changed at any time from the "Settings" menu. + - + %1: @@ -675,8 +692,8 @@ These settings can be changed at any time from the "Settings" menu. create - - + + New %1 %2 created. @@ -693,16 +710,175 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. + + error + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + + + + + Parse error [%1:%2]: %3 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Function definition is not permitted. + + + + + Expected variable for assignment. + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + First argument to map is not a function. + + + + + Second argument to map is not an array. + + + + + First argument to fold is not a function. + + + + + Second argument to fold is not an array. + + + + + First argument to filter is not a function. + + + + + Second argument to filter is not an array. + + + + + Second argument to indexOf is not a string or array. + + + + + Second argument to join is not an array. + + + + + EOF + + + + + No object found with names %1. + + + + + No object found with name %1. + + + + + Object cannot be dependent on itself. + + + + + expression + + + LogarithmPlotter - Parsing error + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + function @@ -729,14 +905,14 @@ These settings can be changed at any time from the "Settings" menu. - - + + low-pass - - + + high-pass @@ -776,8 +952,8 @@ Please make sure your latex installation is correct and report a bug if so. name - - + + %1 %2 renamed to %3. @@ -945,11 +1121,11 @@ Please make sure your latex installation is correct and report a bug if so. - + - - + + labelPosition @@ -963,10 +1139,10 @@ Please make sure your latex installation is correct and report a bug if so. - + - + labelX @@ -1015,14 +1191,14 @@ Please make sure your latex installation is correct and report a bug if so. - + x - + y @@ -1032,17 +1208,17 @@ Please make sure your latex installation is correct and report a bug if so. - + probabilities - + text - + disableLatex diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 35ee738..fe53735 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -167,44 +167,88 @@ Fermer + + CustomPropertyList + + + + + Create new %1 + + Créer un nouvel objet %1 + + + + Dialog + + + Edit properties of %1 %2 + Changer les propriétés de %1 %2 + + + + LogarithmPlotter - Invalid object name + + + + + An object with the name '%1' already exists. + + + + + Name + Nom + + + + Label content + Étiquette + + + + null + vide + + + + name + nom + + + + name + value + nom + valeur + + EditorDialog - Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 - Name - Nom + Nom - Label content - Étiquette + Étiquette - null - vide + vide - name - nom + nom - name + value - nom + valeur + nom + valeur - - + Create new %1 Traduction non litéralle pour éviter les problèmes de genre. - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 @@ -335,37 +379,37 @@ These settings can always be changed at any time from the "Settings" m Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not save file: Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -391,29 +435,52 @@ These settings can always be changed at any time from the "Settings" m Montrer tous les %1 - Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 - Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 - Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 - Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 - Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 + + + + ObjectRow + + + Hide %1 %2 + Cacher l'objet %1 %2 + + + + Show %1 %2 + Montrer l'objet %1 %2 + + + + Set %1 %2 position + Définir la position de l'objet %1 %2 + + + + Delete %1 %2 + Supprimer l'objet %1 %2 + + + + Pick new color for %1 %2 + Choisissez une nouvelle couleur pour %1 %2 @@ -655,7 +722,7 @@ These settings can always be changed at any time from the "Settings" m Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) - + Note: Specify the probability for each value. Note : Spécifiez la probabilité pour chaque valeur. @@ -666,7 +733,7 @@ These settings can always be changed at any time from the "Settings" m Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… - + If you have latex enabled, you can use use latex markup in between $$ to create equations. Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -676,8 +743,9 @@ These settings can always be changed at any time from the "Settings" m + - + %1: %1 : @@ -685,8 +753,8 @@ These settings can always be changed at any time from the "Settings" m create - - + + New %1 %2 created. Nouvel objet %1 %2 créé. @@ -703,16 +771,175 @@ These settings can always be changed at any time from the "Settings" m editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 modifiée de "%4" à "%5". - + %1 of %2 changed from %3 to %4. %1 de %2 modifiée de %3 à %4. + + error + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + + + + + Parse error [%1:%2]: %3 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Function definition is not permitted. + + + + + Expected variable for assignment. + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + First argument to map is not a function. + + + + + Second argument to map is not an array. + + + + + First argument to fold is not a function. + + + + + Second argument to fold is not an array. + + + + + First argument to filter is not a function. + + + + + Second argument to filter is not an array. + + + + + Second argument to indexOf is not a string or array. + + + + + Second argument to join is not an array. + + + + + EOF + + + + + No object found with names %1. + + + + + No object found with name %1. + + + + + Object cannot be dependent on itself. + + + + + expression + + + LogarithmPlotter - Parsing error + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + function @@ -739,14 +966,14 @@ These settings can always be changed at any time from the "Settings" m Gains de Bode - - + + low-pass passe-bas - - + + high-pass passe-haut @@ -822,8 +1049,8 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c name - - + + %1 %2 renamed to %3. %1 %2 renommé(e) en %3. @@ -991,11 +1218,11 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c - + - - + + labelPosition Position de l'étiquette @@ -1009,10 +1236,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c - + - + labelX Position en X de l'étiquette @@ -1061,14 +1288,14 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c - + x X - + y Y @@ -1078,17 +1305,17 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Style du point - + probabilities Liste de probabilités - + text Contenu - + disableLatex Désactiver le rendu LaTeX pour ce texte diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 5d07339..124f1ac 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -166,43 +166,87 @@ Kész + + CustomPropertyList + + + + + Create new %1 + + Új %1 létrehozása + + + + Dialog + + + Edit properties of %1 %2 + %1 %2 tulajdonságainak szerkesztése + + + + LogarithmPlotter - Invalid object name + + + + + An object with the name '%1' already exists. + + + + + Name + Név + + + + Label content + Címke tartalom + + + + null + üres + + + + name + név + + + + name + value + név + érték + + EditorDialog - Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése - Name - Név + Név - Label content - Címke tartalom + Címke tartalom - null - üres + üres - name - név + név - name + value - név + érték + név + érték - - + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása @@ -327,37 +371,37 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not save file: A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -383,29 +427,52 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Összes %1 megjelenítése - Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése - Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése - Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása - Delete %1 %2 - %1 %2 törlése + %1 %2 törlése - Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 + + + + ObjectRow + + + Hide %1 %2 + %1 %2 elrejtése + + + + Show %1 %2 + %1 %2 megjelenítése + + + + Set %1 %2 position + %1 %2 helye beállítása + + + + Delete %1 %2 + %1 %2 törlése + + + + Pick new color for %1 %2 + Válasszon új színt a következőhöz: %1 %2 @@ -647,7 +714,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) - + Note: Specify the probability for each value. Megjegyzés: Adja meg az egyes értékek valószínűségét. @@ -657,7 +724,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … - + If you have latex enabled, you can use use latex markup in between $$ to create equations. Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -667,8 +734,9 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. + - + %1: %1: @@ -676,8 +744,8 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create - - + + New %1 %2 created. Új %1 %2 létrehozva. @@ -694,16 +762,175 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. - + %1 of %2 changed from %3 to %4. %1/%2 megváltozott. Régi érték: %3, új érték: %4. + + error + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + + + + + Parse error [%1:%2]: %3 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Function definition is not permitted. + + + + + Expected variable for assignment. + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + First argument to map is not a function. + + + + + Second argument to map is not an array. + + + + + First argument to fold is not a function. + + + + + Second argument to fold is not an array. + + + + + First argument to filter is not a function. + + + + + Second argument to filter is not an array. + + + + + Second argument to indexOf is not a string or array. + + + + + Second argument to join is not an array. + + + + + EOF + + + + + No object found with names %1. + + + + + No object found with name %1. + + + + + Object cannot be dependent on itself. + + + + + expression + + + LogarithmPlotter - Parsing error + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + function @@ -730,14 +957,14 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Bode-nagyságrendek - - + + low-pass aluláteresztő - - + + high-pass felüláteresztő @@ -809,8 +1036,8 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents name - - + + %1 %2 renamed to %3. %1 %2 átnevezve erre: %3. @@ -978,11 +1205,11 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents - + - - + + labelPosition Címke helyzete @@ -996,10 +1223,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents - + - + labelX Címke X helyzete @@ -1048,14 +1275,14 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents - + x X - + y Y @@ -1065,17 +1292,17 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Pontstílus - + probabilities Valószínűségek listája - + text Tartalom - + disableLatex LaTeX-megjelenítés letiltása ennél a szövegnél diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index f1191ee..f604460 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -166,43 +166,87 @@ + + CustomPropertyList + + + + + Create new %1 + + Opprett nytt %1 + + + + Dialog + + + Edit properties of %1 %2 + Rediger egenskaper for %1 %2 + + + + LogarithmPlotter - Invalid object name + + + + + An object with the name '%1' already exists. + + + + + Name + Navn + + + + Label content + Etikett-innhold + + + + null + NULL + + + + name + navn + + + + name + value + navn + veri + + EditorDialog - Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 - Name - Navn + Navn - Label content - Etikett-innhold + Etikett-innhold - null - NULL + NULL - name - navn + navn - name + value - navn + veri + navn + veri - - + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 @@ -327,37 +371,37 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not save file: Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -383,29 +427,52 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Vis alle %1 - Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 - Show %1 %2 - Vis %1 %2 + Vis %1 %2 - + Set %1 %2 position + Sett %1 %2 posisjon + + + Delete %1 %2 + Slett %1 %2 + + + Pick new color for %1 %2 + Velg ny farge for %1 %2 + + + + ObjectRow + + + Hide %1 %2 + Skjul %1 %2 + + + + Show %1 %2 + Vis %1 %2 + + + Set %1 %2 position Sett %1 %2 posisjon - + Delete %1 %2 - Slett %1 %2 + Slett %1 %2 - + Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 @@ -647,7 +714,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Note: Specify the probability for each value. @@ -657,7 +724,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -667,8 +734,9 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + - + %1: @@ -676,8 +744,8 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. create - - + + New %1 %2 created. Ny %1 %2 opprettet. @@ -694,16 +762,175 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 av %2 %3 endret fra «%4» til «%5». - + %1 of %2 changed from %3 to %4. + + error + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + + + + + Parse error [%1:%2]: %3 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Function definition is not permitted. + + + + + Expected variable for assignment. + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + First argument to map is not a function. + + + + + Second argument to map is not an array. + + + + + First argument to fold is not a function. + + + + + Second argument to fold is not an array. + + + + + First argument to filter is not a function. + + + + + Second argument to filter is not an array. + + + + + Second argument to indexOf is not a string or array. + + + + + Second argument to join is not an array. + + + + + EOF + + + + + No object found with names %1. + + + + + No object found with name %1. + + + + + Object cannot be dependent on itself. + + + + + expression + + + LogarithmPlotter - Parsing error + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + function @@ -730,14 +957,14 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Bode-magnituder - - + + low-pass lavpass - - + + high-pass høypass @@ -800,8 +1027,8 @@ Please make sure your latex installation is correct and report a bug if so. name - - + + %1 %2 renamed to %3. @@ -969,11 +1196,11 @@ Please make sure your latex installation is correct and report a bug if so. - + - - + + labelPosition @@ -987,10 +1214,10 @@ Please make sure your latex installation is correct and report a bug if so. - + - + labelX @@ -1039,14 +1266,14 @@ Please make sure your latex installation is correct and report a bug if so. - + x - + y @@ -1056,17 +1283,17 @@ Please make sure your latex installation is correct and report a bug if so. - + probabilities - + text - + disableLatex diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 506d6a7..a22d858 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -167,43 +167,56 @@ - EditorDialog + CustomPropertyList - + + + + Create new %1 + + + + + Dialog + + Edit properties of %1 %2 - + + LogarithmPlotter - Invalid object name + + + + + An object with the name '%1' already exists. + + + + Name - + Label content - + null - + name - + name + value - - - - + Create new %1 - - FileDialog @@ -326,37 +339,37 @@ These settings can be changed at any time from the "Settings" menu. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -381,28 +394,31 @@ These settings can be changed at any time from the "Settings" menu.Show all %1 + + + ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -646,7 +662,7 @@ These settings can be changed at any time from the "Settings" menu. - + Note: Specify the probability for each value. @@ -656,7 +672,7 @@ These settings can be changed at any time from the "Settings" menu. - + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -666,8 +682,9 @@ These settings can be changed at any time from the "Settings" menu. + - + %1: @@ -675,8 +692,8 @@ These settings can be changed at any time from the "Settings" menu. create - - + + New %1 %2 created. @@ -693,16 +710,175 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. + + error + + + + Cannot find property %1 of object %2. + + + + + Undefined variable %1. + + + + + %1 cannot be executed. + + + + + + + Invalid expression. + + + + + Invalid expression (parity). + + + + + Unknown character "%1". + + + + + + Illegal escape sequence: %1. + + + + + + Parse error [%1:%2]: %3 + + + + + Expected %1 + + + + + Unexpected %1 + + + + + Function definition is not permitted. + + + + + Expected variable for assignment. + + + + + Unexpected ".": member access is not permitted + + + + + Unexpected "[]": arrays are disabled. + + + + + Unexpected symbol: %1. + + + + + First argument to map is not a function. + + + + + Second argument to map is not an array. + + + + + First argument to fold is not a function. + + + + + Second argument to fold is not an array. + + + + + First argument to filter is not a function. + + + + + Second argument to filter is not an array. + + + + + Second argument to indexOf is not a string or array. + + + + + Second argument to join is not an array. + + + + + EOF + + + + + No object found with names %1. + + + + + No object found with name %1. + + + + + Object cannot be dependent on itself. + + + + + expression + + + LogarithmPlotter - Parsing error + + + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + + function @@ -729,14 +905,14 @@ These settings can be changed at any time from the "Settings" menu. - - + + low-pass - - + + high-pass @@ -776,8 +952,8 @@ Please make sure your latex installation is correct and report a bug if so. name - - + + %1 %2 renamed to %3. @@ -945,11 +1121,11 @@ Please make sure your latex installation is correct and report a bug if so. - + - - + + labelPosition @@ -963,10 +1139,10 @@ Please make sure your latex installation is correct and report a bug if so. - + - + labelX @@ -1015,14 +1191,14 @@ Please make sure your latex installation is correct and report a bug if so. - + x - + y @@ -1032,17 +1208,17 @@ Please make sure your latex installation is correct and report a bug if so. - + probabilities - + text - + disableLatex From 1ceccc15cf1e8548903012938a617a4752187b77 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 00:04:55 +0000 Subject: [PATCH 042/436] Translated using Weblate (English) Currently translated at 100.0% (236 of 236 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 89 ++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index a29b1d9..36f7cca 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -172,7 +172,7 @@ + Create new %1 - + Create new %1 + + Create new %1 @@ -180,42 +180,42 @@ Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 LogarithmPlotter - Invalid object name - + LogarithmPlotter - Invalid object name An object with the name '%1' already exists. - + An object with the name '%1' already exists. Name - Name + Name Label content - Label content + Label content null - null + null name - name + name name + value - name + value + name + value @@ -452,27 +452,27 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - Hide %1 %2 + Hide %1 %2 Show %1 %2 - Show %1 %2 + Show %1 %2 Set %1 %2 position - Set %1 %2 position + Set %1 %2 position Delete %1 %2 - Delete %1 %2 + Delete %1 %2 Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 @@ -778,141 +778,141 @@ These settings can be changed at any time from the "Settings" menu. Cannot find property %1 of object %2. - + Cannot find property %1 of object %2. Undefined variable %1. - + Undefined variable %1. %1 cannot be executed. - + %1 is not a function. Invalid expression. - + Invalid expression. Invalid expression (parity). - + Invalid expression (parity). Unknown character "%1". - + Unknown character "%1". Illegal escape sequence: %1. - + Illegal escape sequence: %1. Parse error [%1:%2]: %3 - + Parse error [%1:%2]: %3 Expected %1 - + Expected %1 Unexpected %1 - + Unexpected %1 Function definition is not permitted. - + Function definition is not permitted. Expected variable for assignment. - + Expected variable for assignment. Unexpected ".": member access is not permitted - + Unexpected ".": member access is not permitted Unexpected "[]": arrays are disabled. - + Unexpected "[]": arrays are disabled. Unexpected symbol: %1. - + Unexpected symbol: %1. First argument to map is not a function. - + First argument to map is not a function. Second argument to map is not an array. - + Second argument to map is not an array. First argument to fold is not a function. - + First argument to fold is not a function. Second argument to fold is not an array. - + Second argument to fold is not an array. First argument to filter is not a function. - + First argument to filter is not a function. Second argument to filter is not an array. - + Second argument to filter is not an array. Second argument to indexOf is not a string or array. - + Second argument to indexOf is not a string or array. Second argument to join is not an array. - + Second argument to join is not an array. EOF - + End of expression No object found with names %1. - + No object found with names %1. No object found with name %1. - + No object found with name %1. Object cannot be dependent on itself. - + Object cannot be dependent on itself. @@ -920,7 +920,7 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - Parsing error - + LogarithmPlotter - Parsing error @@ -928,7 +928,10 @@ These settings can be changed at any time from the "Settings" menu. - + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 From acadad2bd1c9b2530cc4fb1513169854504d6310 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 00:25:06 +0000 Subject: [PATCH 043/436] Translated using Weblate (German) Currently translated at 100.0% (236 of 236 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 89 ++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 9a88e3a..6a90d67 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -172,7 +172,7 @@ + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen @@ -180,42 +180,42 @@ Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten LogarithmPlotter - Invalid object name - + LogarithmPlotter - Ungültiger Objektname An object with the name '%1' already exists. - + Ein Objekt mit dem Namen '%1' existiert bereits. Name - Name + Name Label content - Etikett + Etikett null - leer + leer name - Name + Name name + value - Name + Wert + Name + Wert @@ -452,27 +452,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen Delete %1 %2 - %1 %2 löschen + %1 %2 löschen Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen @@ -778,141 +778,141 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Cannot find property %1 of object %2. - + Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. Undefined variable %1. - + Die Variable %1 ist nicht definiert. %1 cannot be executed. - + %1 ist keine Formel. Invalid expression. - + Ungültiger Ausdruck. Invalid expression (parity). - + Ungültiger Ausdruck (Parität). Unknown character "%1". - + Unbekanntes Schriftzeichen "%1". Illegal escape sequence: %1. - + Unzulässige Escapesequenz: %1. Parse error [%1:%2]: %3 - + Analysefehler [%1:%2]: %3 Expected %1 - + Erwartet %1 Unexpected %1 - + Unerwartetes %1 Function definition is not permitted. - + Funktionsdefinition ist nicht erlaubt. Expected variable for assignment. - + Erwartete Variable für Zuweisung. Unexpected ".": member access is not permitted - + Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt Unexpected "[]": arrays are disabled. - + Unerwartetes "[]": Arrays sind deaktiviert. Unexpected symbol: %1. - + Unerwartetes Symbol: %1. First argument to map is not a function. - + Der erste Parameter von map ist keine Formel. Second argument to map is not an array. - + Der zweite Parameter von map ist kein Array. First argument to fold is not a function. - + Der erste Parameter für fold ist keine Formel. Second argument to fold is not an array. - + Der zweite Parameter für fold ist kein Array. First argument to filter is not a function. - + Der erste Parameter für filter ist keine Formel. Second argument to filter is not an array. - + Der zweite Parameter von filter ist kein Array. Second argument to indexOf is not a string or array. - + Der zweite Parameter von indexOf ist kein String oder Array. Second argument to join is not an array. - + Der zweite Parameter von join ist kein Array. EOF - + Ende des Ausdrucks No object found with names %1. - + Kein Objekt mit Namen %1 gefunden. No object found with name %1. - + Kein Objekt mit dem Namen %1 gefunden. Object cannot be dependent on itself. - + Ein Objekt kann nicht von sich selbst abhängen. @@ -920,7 +920,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter - Parsing error - + LogarithmPlotter - Analysefehler @@ -928,7 +928,10 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" %2 Evaluated expression: %3 - + Fehler beim Analysieren des Ausdrucks für die Eigenschaft %1: +%2 + +Ausdruck analysiert: %3 From 7686204786b8b9a69eb02e383d0e219f8f913270 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 00:12:44 +0000 Subject: [PATCH 044/436] Translated using Weblate (French) Currently translated at 100.0% (236 of 236 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 89 ++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index fe53735..63cabca 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -173,7 +173,7 @@ + Create new %1 - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 @@ -181,42 +181,42 @@ Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 LogarithmPlotter - Invalid object name - + LogarithmPlotter - Nom d'objet invalide An object with the name '%1' already exists. - + Un objet portant le nom '%1' existe déjà. Name - Nom + Nom Label content - Étiquette + Étiquette null - vide + vide name - nom + nom name + value - nom + valeur + nom + valeur @@ -460,27 +460,27 @@ These settings can always be changed at any time from the "Settings" m Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 @@ -787,141 +787,141 @@ These settings can always be changed at any time from the "Settings" m Cannot find property %1 of object %2. - + Impossible de trouver la propriété %1 de l'objet %2. Undefined variable %1. - + La variable %1 n'est pas définie. %1 cannot be executed. - + %1 n'est pas une fonction. Invalid expression. - + Formule invalide. Invalid expression (parity). - + Formule invalide (parité). Unknown character "%1". - + Le caractère "%1" est inconnu. Illegal escape sequence: %1. - + Séquence d'échappement illégale : %1. Parse error [%1:%2]: %3 - + Erreur de syntaxe [%1:%2] : %3 Expected %1 - + %1 attendu Unexpected %1 - + %1 inattendu Function definition is not permitted. - + La définition de fonctions n'est pas autorisée. Expected variable for assignment. - + Une variable est attendue pour l'affectation. Unexpected ".": member access is not permitted - + "." inattendu : l'accès aux propriétés n'est pas autorisé Unexpected "[]": arrays are disabled. - + "[]" inattendu : les tableaux sont désactivés. Unexpected symbol: %1. - + Symbole inconnu : %1. First argument to map is not a function. - + Le premier argument de map n'est pas une fonction. Second argument to map is not an array. - + Le deuxième argument de map n'est pas un tableau. First argument to fold is not a function. - + Le premier argument de fold n'est pas une fonction. Second argument to fold is not an array. - + Le deuxième argument de fold n'est pas un tableau. First argument to filter is not a function. - + Le premier argument de filter n'est pas une fonction. Second argument to filter is not an array. - + Le deuxième argument de filter n'est pas un tableau. Second argument to indexOf is not a string or array. - + Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. Second argument to join is not an array. - + Le deuxième argument de join n'est pas un tableau. EOF - + Fin de la formule No object found with names %1. - + Aucun objet trouvé ayant pour noms %1. No object found with name %1. - + Aucun objet avec le nom %1 n'a été trouvé. Object cannot be dependent on itself. - + Un objet ne peut pas dépendre de lui-même. @@ -929,7 +929,7 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter - Parsing error - + LogarithmPlotter - Erreur de syntaxe @@ -937,7 +937,10 @@ These settings can always be changed at any time from the "Settings" m %2 Evaluated expression: %3 - + Erreur lors de l'analyse de la formule pour la propriété %1 : +%2 + +Formule analysée : %3 From ddb5156396c3d8608cbd6123cb2306aeacc1abfb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 02:49:43 +0200 Subject: [PATCH 045/436] Fixing mistranslated string. --- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 7ac669a..6a3d828 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -1071,7 +1071,7 @@ ParserState.prototype.expect = function (type, value) { var coords = this.tokens.getCoordinates(); throw new Error(qsTranslate('error', 'Parse error [%1:%2]: %3') .arg(coords.line).arg(coords.column) - .arg(qsTranslate('error', 'Expected %1').arg(qsTranslate('error',value) || type))); + .arg(qsTranslate('error', 'Expected %1').arg(value || type))); } }; From de1be925b0ea86938a7b89cd63ce161630f3c5ac Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 02:55:23 +0200 Subject: [PATCH 046/436] Removing unneeded and buggy simplifications. --- .../qml/eu/ad5001/LogarithmPlotter/js/utils.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index ed3a8f5..da52902 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -128,14 +128,14 @@ function textsub(text) { function simplifyExpression(str) { var replacements = [ // Operations not done by parser. - [// Decomposition way 2 - /(^|[+-] |\()([-.\d\w]+) ([*/]) \((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\)($| [+-]|\))/g, - "$1$2 $3 $4 $6 $2 $3 $7$9" - ], - [ // Decomposition way 2 - /(^|[+-] |\()\((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\) ([*/]) ([-.\d\w]+)($| [+-]|\))/g, - "$1$2 $7 $8 $4 $5 $7 $8$9" - ], + // [// Decomposition way 2 + // /(^|[+-] |\()([-.\d\w]+) ([*/]) \((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\)($| [+-]|\))/g, + // "$1$2 $3 $4 $6 $2 $3 $7$9" + // ], + // [ // Decomposition way 2 + // /(^|[+-] |\()\((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\) ([*/]) ([-.\d\w]+)($| [+-]|\))/g, + // "$1$2 $7 $8 $4 $5 $7 $8$9" + // ], [ // Factorisation of π elements. /(([-\d\w.]+ [*/] )*)(pi|π)(( [/*] [-\d\w.]+)*) ([+-]) (([-\d\w.]+ [*/] )*)(pi|π)(( [/*] [-\d\w.]+)*)?/g, function(match, m1, n1, pi1, m2, ope2, n2, opeM, m3, n3, pi2, m4, ope4, n4) { From c5851e6d958cbe0dd36847d831ea45283c129560 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 17:11:54 +0200 Subject: [PATCH 047/436] Adding new 'Position setting' history action. --- LogarithmPlotter/i18n/lp_de.ts | 61 +++++++----- LogarithmPlotter/i18n/lp_en.ts | 61 +++++++----- LogarithmPlotter/i18n/lp_es.ts | 61 +++++++----- LogarithmPlotter/i18n/lp_fr.ts | 61 +++++++----- LogarithmPlotter/i18n/lp_hu.ts | 61 +++++++----- LogarithmPlotter/i18n/lp_nb_NO.ts | 61 +++++++----- LogarithmPlotter/i18n/lp_template.ts | 61 +++++++----- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 8 +- .../LogarithmPlotter/LogarithmPlotter.qml | 12 ++- .../LogarithmPlotter/PickLocationOverlay.qml | 53 ++++++----- .../LogarithmPlotter/js/history/common.js | 65 ++++++++++++- .../js/history/editproperty.js | 4 +- .../LogarithmPlotter/js/history/position.js | 95 +++++++++++++++++++ .../ad5001/LogarithmPlotter/js/historylib.js | 3 + .../ad5001/LogarithmPlotter/js/math/latex.js | 8 ++ 15 files changed, 470 insertions(+), 205 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 6a90d67..ff300e6 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -103,52 +103,52 @@ LaTeX-Rendering aktivieren - + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -346,62 +346,62 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter - + Objects Objekte - + Settings Einstellungen - + History Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not save file: Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -478,12 +478,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" PickLocationOverlay - + Pointer precision: Genauigkeit des Zeigers: - + Snap to grid Am Gitter einrasten @@ -1190,6 +1190,19 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Punkte + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + prop diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 36f7cca..d51714e 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -103,52 +103,52 @@ Enable LaTeX rendering - + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -346,62 +346,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects Objects - + Settings Settings - + History History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not save file: Could not save file: - + Loaded file '%1'. Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -478,12 +478,12 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: Pointer precision: - + Snap to grid Snap to grid @@ -1190,6 +1190,19 @@ Please make sure your LaTeX installation is correct and report a bug if so.Points + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + prop diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 0842196..dfaf15b 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -103,52 +103,52 @@ Activar el renderizado de LaTeX - + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -314,62 +314,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects - + Settings - + History - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -426,12 +426,12 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid @@ -1099,6 +1099,19 @@ Please make sure your latex installation is correct and report a bug if so. + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + prop diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 63cabca..034e753 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -104,52 +104,52 @@ Activer le rendu LaTeX - + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -354,62 +354,62 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter - + Objects Objets - + Settings Paramètres - + History Historique - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not save file: Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -486,12 +486,12 @@ These settings can always be changed at any time from the "Settings" m PickLocationOverlay - + Pointer precision: Précision du pointeur : - + Snap to grid Placement sur la grille @@ -1199,6 +1199,19 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Points + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + prop diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 124f1ac..a2c2163 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -103,52 +103,52 @@ LaTeX-megjelenítés engedélyezése - + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -346,62 +346,62 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter - + Objects Tárgyak - + Settings Beállítások - + History Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not save file: A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -478,12 +478,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. PickLocationOverlay - + Pointer precision: Mutató pontossága: - + Snap to grid Rácshoz illesztés @@ -1183,6 +1183,19 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Pontok + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + prop diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index f604460..dfdfd34 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -103,52 +103,52 @@ - + &Help &Hjelp - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -346,62 +346,62 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. LogarithmPlotter - + Objects Objekter - + Settings Innstillinger - + History Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not save file: Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -478,12 +478,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. PickLocationOverlay - + Pointer precision: Peker-presisjon: - + Snap to grid Fest til rutenett @@ -1174,6 +1174,19 @@ Please make sure your latex installation is correct and report a bug if so.Punkter + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + prop diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index a22d858..f525586 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -103,52 +103,52 @@ - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -314,62 +314,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects - + Settings - + History - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -426,12 +426,12 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid @@ -1099,6 +1099,19 @@ Please make sure your latex installation is correct and report a bug if so. + + position + + + Position of %1 %2 set from "%3" to "%4". + + + + + Position of %1 set from %2 to %3. + + + prop diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 31d9b7b..48cf383 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -22,7 +22,7 @@ import QtQuick.Dialogs 1.3 import eu.ad5001.MixedMenu 1.1 import "js/objects.js" as Objects import "js/historylib.js" as HistoryLib -import "js/math/latex.js" as Latex +import "js/math/latex.js" as LatexJS /*! @@ -143,18 +143,16 @@ MenuBar { } Action { - id: enableLatexSetting + id: enableLatexJSSetting text: qsTr("Enable LaTeX rendering") checkable: true checked: Helper.getSettingBool("enable_latex") onTriggered: { Helper.setSettingBool("enable_latex", checked) - Latex.enabled = checked + LatexJS.enabled = checked drawCanvas.requestPaint() } icon.name: 'Expression' - - Component.onCompleted: Latex.enabled = checked } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 445c03c..0c71421 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -25,6 +25,7 @@ import QtQuick 2.12 import "js/objs/autoload.js" as ALObjects import "js/objects.js" as Objects +import "js/math/latex.js" as LatexJS import eu.ad5001.LogarithmPlotter.History 1.0 import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup @@ -44,7 +45,16 @@ ApplicationWindow { color: sysPalette.window title: "LogarithmPlotter " + (settings.saveFilename != "" ? " - " + settings.saveFilename.split('/').pop() : "") + (history.saved ? "" : "*") - SystemPalette { id: sysPalette; colorGroup: SystemPalette.Active } + SystemPalette { + id: sysPalette; colorGroup: SystemPalette.Active + + Component.onCompleted: { + // LatexJS initialization. + LatexJS.enabled = Helper.getSettingBool("enable_latex") + LatexJS.Renderer = Latex + LatexJS.defaultColor = sysPalette.windowText + } + } SystemPalette { id: sysPaletteIn; colorGroup: SystemPalette.Disabled } menuBar: appMenu.trueItem diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 8ef80d6..7e59fd5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -92,34 +92,29 @@ Item { acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: { if(mouse.button == Qt.LeftButton) { // Validate - if(parent.pickX) { - let newValue = picked.mouseX.toString() - newValue = { - 'Expression': () => new MathLib.Expression(newValue), - 'number': () => parseFloat(newValue) - }[Objects.types[objType].properties()[propertyX]]() - let obj = Objects.currentObjectsByName[objName] // getObjectByName(objName, objType) - history.addToHistory(new HistoryLib.EditedProperty( - objName, objType, propertyX, obj[propertyX], newValue + let newValueX = !parent.pickX ? null : parseValue(picked.mouseX.toString(), objType, propertyX) + let newValueY = !parent.pickY ? null : parseValue(picked.mouseY.toString(), objType, propertyY) + let obj = Objects.currentObjectsByName[objName] + // Set values + if(parent.pickX && parent.pickY) { + history.addToHistory(new HistoryLib.EditedPosition( + objName, objType, obj[propertyX], newValueX, obj[propertyY], newValueY )) - obj[propertyX] = newValue - obj.update() - objectLists.update() - } - if(parent.pickY) { - let newValue = picked.mouseY.toString() - newValue = { - 'Expression': () => new MathLib.Expression(newValue), - 'number': () => parseFloat(newValue) - }[Objects.types[objType].properties()[propertyY]]() - let obj = Objects.currentObjectsByName[objName] // Objects.getObjectByName(objName, objType) + obj[propertyX] = newValueX + obj[propertyY] = newValueY + } else if(parent.pickX) { history.addToHistory(new HistoryLib.EditedProperty( - objName, objType, propertyY, obj[propertyY], newValue + objName, objType, propertyX, obj[propertyX], newValueX )) - obj[propertyY] = newValue - obj.update() - objectLists.update() + obj[propertyX] = newValueX + } else if(parent.pickY) { + history.addToHistory(new HistoryLib.EditedProperty( + objName, objType, propertyY, obj[propertyY], newValueY + )) + obj[propertyY] = newValueY } + obj.update() + objectLists.update() } pickerRoot.visible = false; } @@ -214,4 +209,14 @@ Item { } + /*! + \qmlmethod void History::parseValue(string value, string objType, string propertyName) + Parses a given \c value as an expression or a number depending on the type of \c propertyName of all \c objType. + */ + function parseValue(value, objType, propertyName) { + return { + 'Expression': () => new MathLib.Expression(value), + 'number': () => parseFloat(value) + }[Objects.types[objType].properties()[propertyName]]() + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js index 16f9c6e..92811d9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js @@ -18,14 +18,27 @@ .pragma library +.import "../math/latex.js" as Latex + var themeTextColor; +var imageDepth = 2; +var fontSize = 14; class Action { - // Type of the action done. + /** + * Type of the action. + * + * @returns {string} + */ type(){return 'Unknown'} - // Icon associated with the item + /** + * Icon associated with the action. + * + * @returns {string} + */ + icon(){return 'position'} // TargetName is the name of the object that's targeted by the event. constructor(targetName = "", targetType = "Point") { @@ -33,25 +46,67 @@ class Action { this.targetType = targetType } + /** + * Undoes the action. + * + * @returns {string} + */ undo() {} + /** + * Redoes the action. + * + * @returns {string} + */ redo() {} + /** + * Export the action to a serializable format. + * NOTE: These arguments will be reinputed in the constructor in this order. + * + * @returns {string} + */ export() { return [this.targetName, this.targetType] } - // String used in the toolkit + /** + * Returns a string with the human readable description of the action. + * + * @returns {string} + */ getReadableString() { return 'Unknown action' } - // Returns an HTML tag containing the icon of a type + /** + * Returns a string containing an HTML tag describing the icon of a type + * + * @param {string} type - Name of the icon to put in rich text. + * @returns {string} + */ getIconRichText(type) { return `` } - // String used in the preview + /** + * 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} + */ + renderLatexAsHtml(latexString) { + if(!Latex.enabled) + throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") + let latexInfo = Latex.Renderer.render(latexString, imageDepth*fontSize+4, themeTextColor).split(",") + return `` + } + + /** + * Returns a string with the HTML-formated description of the action. + * + * @returns {string} + */ getHTMLString() { return this.getReadableString() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js index 9641967..3fca7b6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js @@ -94,8 +94,8 @@ class EditedProperty extends C.Action { this.next = this.newValue.name.join(",") break; case "Dict": - this.prev = JSON.stringify(this.previousValue).replace("'", "\\'").replace('"', "'") - this.next = JSON.stringify(this.newValue).replace("'", "\\'").replace('"', "'") + this.prev = JSON.stringify(this.previousValue) + this.next = JSON.stringify(this.newValue) break; } } else { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js new file mode 100644 index 0000000..d33ad71 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js @@ -0,0 +1,95 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +.pragma library + +.import "../objects.js" as Objects +.import "../mathlib.js" as MathLib +.import "../math/latex.js" as Latex +.import "../utils.js" as Utils +.import "../objs/common.js" as Common +.import "common.js" as C + +class EditedPosition extends C.Action { + // Action used for objects that have a X and Y expression properties (points, texts...) + type(){return 'EditedPosition'} + + icon(){return 'position'} + + color(darkVer=false){ + return darkVer ? 'seagreen' : 'lightseagreen'; + } + + constructor(targetName = "", targetType = "Point", previousXValue = "", newXValue = "", previousYValue = "", newYValue = "") { + super(targetName, targetType) + let imports = { + 'previousXValue': previousXValue, + 'previousYValue': previousYValue, + 'newXValue': newXValue, + 'newYValue': newYValue + } + for(let name in imports) + this[name] = (typeof imports[name]) == 'string' ? new MathLib.Expression(imports[name]) : imports[name] + this.setReadableValues() + } + + undo() { + Objects.currentObjectsByName[this.targetName].x = this.previousXValue + Objects.currentObjectsByName[this.targetName].y = this.previousYValue + Objects.currentObjectsByName[this.targetName].update() + } + + redo() { + Objects.currentObjectsByName[this.targetName].x = this.newXValue + Objects.currentObjectsByName[this.targetName].y = this.newYValue + Objects.currentObjectsByName[this.targetName].update() + } + + setReadableValues() { + this.prevString = `(${this.previousXValue.toString()},${this.previousYValue.toString()})` + this.nextString = `(${this.newXValue.toString()},${this.newYValue.toString()})` + // 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)`) + } else { + this.prevHTML = ' '+Utils.escapeHTML(this.prevString)+' ' + this.nextHTML = ' '+Utils.escapeHTML(this.nextString)+' ' + } + + } + + export() { + return [this.targetName, this.targetType, this.targetProperty, + this.previousXValue.toEditableString(), this.newXValue.toEditableString(), + this.previousYValue.toEditableString(), this.newYValue.toEditableString()] + } + + getReadableString() { + return qsTr('Position of %1 %2 set from "%3" to "%4".') + .arg(Objects.types[this.targetType].displayType()) + .arg(this.targetName).arg(this.prevString).arg(this.nextString) + } + + getHTMLString() { + return qsTr('Position of %1 set from %2 to %3.') + .arg(' ' + this.targetName + ' ') + .arg(this.prevHTML) + .arg(this.nextHTML) + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js index c360cb7..70542af 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js @@ -24,6 +24,7 @@ .import "history/create.js" as Create .import "history/delete.js" as Delete .import "history/editproperty.js" as EP +.import "history/position.js" as Pos .import "history/visibility.js" as V .import "history/name.js" as Name .import "history/color.js" as Color @@ -35,6 +36,7 @@ var Action = Common.Action var CreateNewObject = Create.CreateNewObject var DeleteObject = Delete.DeleteObject var EditedProperty = EP.EditedProperty +var EditedPosition = Pos.EditedPosition var EditedVisibility = V.EditedVisibility var NameChanged = Name.NameChanged var ColorChanged = Color.ColorChanged @@ -44,6 +46,7 @@ var Actions = { "CreateNewObject": CreateNewObject, "DeleteObject": DeleteObject, "EditedProperty": EditedProperty, + "EditedPosition": EditedPosition, "EditedVisibility": EditedVisibility, "NameChanged": NameChanged, "ColorChanged": ColorChanged, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 4c57b07..06d0bfa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -25,6 +25,14 @@ * true if latex has been enabled by the user, false otherwise. */ var enabled = false +/** + * LaTeX python backend QObject. + */ +var Renderer = null +/** + * Default window color used to render LaTeX formulas. + */ +var defaultColor = "black" /** * Puts element within parenthesis. From e98be96b0d3677cfa250505adc91fb22a8ea2bd3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 17:29:35 +0200 Subject: [PATCH 048/436] Latex rendering for property edition history action! --- .../js/history/editproperty.js | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js index 3fca7b6..b2862a2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js @@ -19,6 +19,7 @@ .pragma library .import "../objects.js" as Objects +.import "../math/latex.js" as Latex .import "../mathlib.js" as MathLib .import "../objs/common.js" as Common .import "common.js" as C @@ -77,30 +78,37 @@ class EditedProperty extends C.Action { } setReadableValues() { - this.prev = ""; - this.next = ""; + this.prevString = ""; + this.nextString = ""; if(this.propertyType instanceof Object) { switch(this.propertyType.type) { case "Enum": - this.prev = this.propertyType.translatedValues[this.propertyType.values.indexOf(this.previousValue)] - this.next = this.propertyType.translatedValues[this.propertyType.values.indexOf(this.newValue)] + this.prevString = this.propertyType.translatedValues[this.propertyType.values.indexOf(this.previousValue)] + this.nextString = this.propertyType.translatedValues[this.propertyType.values.indexOf(this.newValue)] break; case "ObjectType": - this.prev = this.previousValue == null ? "null" : this.previousValue.name - this.next = this.newValue == null ? "null" : this.newValue.name + this.prevString = this.previousValue == null ? "null" : this.previousValue.name + this.nextString = this.newValue == null ? "null" : this.newValue.name break; case "List": - this.prev = this.previousValue.join(",") - this.next = this.newValue.name.join(",") + this.prevString = this.previousValue.join(",") + this.nextString = this.newValue.name.join(",") break; case "Dict": - this.prev = JSON.stringify(this.previousValue) - this.next = JSON.stringify(this.newValue) + this.prevString = JSON.stringify(this.previousValue) + this.nextString = JSON.stringify(this.newValue) break; } } else { - this.prev = this.previousValue == null ? "null" : this.previousValue.toString() - this.next = this.newValue == null ? "null" : this.newValue.toString() + this.prevString = this.previousValue == null ? "null" : this.previousValue.toString() + this.nextString = this.newValue == null ? "null" : this.newValue.toString() + } + // HTML + this.prevHTML = ' '+this.prevString+' ' + this.nextHTML = ' '+this.nextString+' ' + if(Latex.enabled && this.propertyType == "Expression") { + this.prevHTML= this.renderLatexAsHtml(this.previousValue.latexMarkup) + this.nextHTML= this.renderLatexAsHtml(this.newValue.latexMarkup) } } @@ -108,16 +116,14 @@ class EditedProperty extends C.Action { return qsTr('%1 of %2 %3 changed from "%4" to "%5".') .arg(this.targetPropertyReadable) .arg(Objects.types[this.targetType].displayType()) - .arg(this.targetName).arg(this.prev).arg(this.next) + .arg(this.targetName).arg(this.prevString).arg(this.nextString) } getHTMLString() { return qsTr('%1 of %2 changed from %3 to %4.') .arg(this.targetPropertyReadable) .arg(' ' + this.targetName + ' ') - .arg(' '+this.prev+' ') - .arg(' '+this.next+' ') -// .arg('' + Objects.types[this.targetType].displayType()) - + .arg(this.prevHTML) + .arg(this.nextHTML) } } From 218c55b4915e66efeaebe8d4a0c8e6f3a21601e1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 17:37:38 +0200 Subject: [PATCH 049/436] Fixing Expression and text not saving changes when having used the input character popup. --- .../qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 1 + .../qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml | 1 + 2 files changed, 2 insertions(+) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 5c43350..0ac6688 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -211,6 +211,7 @@ Item { onSelected: function(c) { editor.insert(editor.cursorPosition, c) insertPopup.close() + focus = false editor.focus = true } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index a823645..1d1073f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -155,6 +155,7 @@ Item { onSelected: function(c) { input.insert(input.cursorPosition, c) insertPopup.close() + focus = false input.focus = true } } From c85dba737dedc22c62b7de31386df9699a4d49e2 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 17:43:33 +0000 Subject: [PATCH 050/436] Translated using Weblate (English) Currently translated at 100.0% (238 of 238 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index d51714e..e78a4a5 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -1195,12 +1195,12 @@ Please make sure your LaTeX installation is correct and report a bug if so. Position of %1 %2 set from "%3" to "%4". - + %1 %2 moved from "%3" to "%4". Position of %1 set from %2 to %3. - + %1 moved from %2 to %3. From 6e21f2eea1f3a7dc72c6396615f980c6742bd0eb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 17:46:36 +0000 Subject: [PATCH 051/436] Translated using Weblate (German) Currently translated at 100.0% (238 of 238 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index ff300e6..6883254 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -1195,12 +1195,12 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Position of %1 %2 set from "%3" to "%4". - + %1 %2 wurde von "%3" nach "%4" verschoben. Position of %1 set from %2 to %3. - + %1 wurde von %2 nach %3 verschoben. From 16efe31b5f3b4671920ec12eac2b4d6809ec1c7e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 17:45:13 +0000 Subject: [PATCH 052/436] Translated using Weblate (French) Currently translated at 100.0% (238 of 238 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 034e753..c6dbf1f 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -1204,12 +1204,12 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Position of %1 %2 set from "%3" to "%4". - + %1 %2 a été déplacé depuis "%3" vers "%4". Position of %1 set from %2 to %3. - + %1 a été déplacé depuis %2 vers %3. From 5da8dcefe527a64a162cbe3fbf5e299cca35c04d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 23:44:04 +0200 Subject: [PATCH 053/436] First crack at autocompletion. --- .../ObjectLists/Editor/Dialog.qml | 3 + .../ObjectLists/ObjectLists.qml | 2 +- .../Setting/ExpressionEditor.qml | 183 +++++++++++++++++- .../LogarithmPlotter/js/parsing/parsing.js | 2 + .../LogarithmPlotter/js/parsing/reference.js | 2 + .../LogarithmPlotter/js/parsing/tokenizer.js | 23 +-- 6 files changed, 193 insertions(+), 22 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index d8c319e..3297139 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -58,6 +58,9 @@ D.Dialog { width: 350 height: 400 + // Disable closing on return/enter, causing issues with autocomplete. + onActionChosen: if(action.key == Qt.Key_Enter || action.key == Qt.Key_Return) action.accepted = false + Label { id: dlgTitle anchors.left: parent.left diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 0ad35ff..99e08a7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -49,7 +49,7 @@ ScrollView { id: objectsListView model: Object.keys(Objects.types) //width: implicitWidth //objectListList.width - (implicitHeight > objectListList.parent.height ? 20 : 0) - implicitHeight: contentItem.childrenRect.height + footer.height + 10 + implicitHeight: contentItem.childrenRect.height + footerItem.height + 10 delegate: ListView { id: objTypeList diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 0ac6688..6ab5f49 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -19,7 +19,7 @@ import QtQuick.Controls 2.12 import QtQuick 2.12 import QtQuick.Dialogs 1.3 as D -import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup +import eu.ad5001.LogarithmPlotter.Popup 1.0 as P import "../js/mathlib.js" as MathLib import "../js/utils.js" as Utils import "../js/parsing/parsing.js" as Parsing @@ -151,6 +151,8 @@ Item { focus: true selectByMouse: true + property var tokens: parent.tokens(text) + Keys.priority: Keys.BeforeItem // Required for knowing which key the user presses. onEditingFinished: { @@ -165,7 +167,38 @@ Item { } } + //onTextEdited: acPopupContent.itemSelected = 0 + + onActiveFocusChanged: { + if(activeFocus) + autocompletePopup.open() + else + autocompletePopup.close() + } + + Keys.onUpPressed: function(event) { + acPopupContent.itemSelected = Math.max(0, acPopupContent.itemSelected-1) + event.accepted = true + } + + Keys.onDownPressed: function(event) { + acPopupContent.itemSelected = Math.max(0,Math.min(acPopupContent.itemCount-1, acPopupContent.itemSelected+1)) + event.accepted = true + } + Keys.onPressed: function(event) { + // Autocomplete popup events + //console.log("Pressed key:", event.key, Qt.Key_Return, Qt.Key_Enter, event.text) + if((event.key == Qt.Key_Enter || event.key == Qt.Key_Return) && acPopupContent.itemCount > 0) { + acPopupContent.autocomplete() + event.accepted = true + } else + acPopupContent.itemSelected = 0 + /*if(event.key == Qt.Key_Left) { // TODO: Don't reset the position when the key moved is still on the same word + if(!acPopupContent.identifierTokenTypes.includes()) + }*/ + + if(event.text in openAndCloseMatches) { let start = selectionStart insert(selectionStart, event.text) @@ -181,11 +214,116 @@ Item { verticalAlignment: TextInput.AlignVCenter horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter textFormat: Text.StyledText - text: colorize(editor.text) + text: colorize(parent.tokens) color: sysPalette.windowText //font.pixelSize: parent.font.pixelSize //opacity: editor.activeFocus ? 0 : 1 } + + Popup { + id: autocompletePopup + x: 0 + y: parent.height + closePolicy: Popup.NoAutoClose + + width: editor.width + height: acPopupContent.height + padding: 0 + + Column { + id: acPopupContent + width: parent.width + + readonly property var identifierTokenTypes: [ + Parsing.TokenType.VARIABLE, + Parsing.TokenType.FUNCTION, + Parsing.TokenType.CONSTANT + ] + property var currentToken: getTokenAt(editor.tokens, editor.cursorPosition) + visible: currentToken != null && identifierTokenTypes.includes(currentToken.type) + + // Focus handling. + readonly property var lists: [functionsList] + readonly property int itemCount: functionsList.model.length + property int itemSelected: 0 + + /*! + \qmlmethod var ExpressionEditor::autocompleteAt(int idx) + Returns the autocompletion text information at a given position. + The information contains key 'text' (description text), 'autocomplete' (text to insert) + and 'cursorFinalOffset' (amount to add to the cursor's position after the end of the autocomplete) + */ + function autocompleteAt(idx) { + if(idx >= itemCount) return "" + let startIndex = 0 + for(let list of lists) { + if(idx < startIndex + list.model.length) + return list.model[idx-startIndex] + startIndex += list.model.length + } + } + /*! + \qmlmethod var ExpressionEditor::autocomplete() + Autocompletes with the current selected word. + */ + function autocomplete() { + let autotext = autocompleteAt(itemSelected) + let startPos = currentToken.startPosition + console.log("Autocompleting",autotext.text,startPos) + editor.remove(startPos, startPos+currentToken.value.length) + editor.insert(startPos, autotext.autocomplete) + editor.cursorPosition = startPos+autotext.autocomplete.length+autotext.cursorFinalOffset + } + + ListView { + id: functionsList + //anchors.fill: parent + property int itemStartIndex: 0 + width: parent.width + visible: model.length > 0 + implicitHeight: contentItem.childrenRect.height + headerItem.height + model: parent.visible ? + Parsing.FUNCTIONS_LIST.filter((name) => name.includes(acPopupContent.currentToken.value)) + .map((name) => {return {'text': name, 'autocomplete': name+'()', 'cursorFinalOffset': -1}}) : [] + + header: Column { + width: functionsList.width + spacing: 2 + topPadding: 5 + bottomPadding: 5 + + Text { + leftPadding: 5 + text: qsTr("Functions") + } + + Rectangle { + height: 1 + color: 'black' + width: parent.width + } + } + + delegate: Rectangle { + property bool selected: index + functionsList.itemStartIndex == acPopupContent.itemSelected + + width: funcText.width + height: funcText.height + color: selected ? sysPalette.highlight : 'transparent' + + Text { + id: funcText + topPadding: 2 + bottomPadding: 2 + leftPadding: 15 + text: functionsList.model[index].text + width: functionsList.width + color: parent.selected ? sysPalette.highlightedText : sysPalette.windowText + } + } + } + } + } } Button { @@ -202,7 +340,7 @@ Item { } } - Popup.InsertCharacter { + P.InsertCharacter { id: insertPopup x: Math.round((parent.width - width) / 2) @@ -228,7 +366,6 @@ Item { // Check if the expression is valid, throws error otherwise. if(!expr.allRequirementsFullfilled()) { let undefVars = expr.undefinedVariables() - console.log(JSON.stringify(undefVars), undefVars.join(', ')) if(undefVars.length > 1) throw new Error(qsTranslate('error', 'No object found with names %1.').arg(undefVars.join(', '))) else @@ -245,15 +382,41 @@ Item { } /*! - \qmlmethod var ExpressionEditor::colorize(string expressionText) - Creates an HTML colorized string of the incomplete \c expressionText. + \qmlmethod var ExpressionEditor::tokens(string expressionText) + Generates a list of tokens from the given. + */ + function tokens(text) { + let tokenizer = new Parsing.Tokenizer(new Parsing.Input(text), true, false) + let tokenList = [] + let token + while((token = tokenizer.next()) != null) + tokenList.push(token) + return tokenList + } + + /*! + \qmlmethod var ExpressionEditor::getTokenAt(var tokens, int position) + Gets the token at the given position within the text. + Returns null if out of bounds. + */ + function getTokenAt(tokenList, position) { + let currentPosition = 0 + for(let token of tokenList) + if(position <= (currentPosition + token.value.length)) + return token + else + currentPosition += token.value.length + return null + } + + /*! + \qmlmethod var ExpressionEditor::colorize(var tokenList) + Creates an HTML colorized string of the given tokens. Returns the colorized and escaped expression if possible, null otherwise.. */ - function colorize(text) { - let tokenizer = new Parsing.Tokenizer(new Parsing.Input(text), true, false) + function colorize(tokenList) { let parsedText = "" - let token - while((token = tokenizer.next()) != null) { + for(let token of tokenList) { switch(token.type) { case Parsing.TokenType.VARIABLE: parsedText += `${token.value}` diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js index c1e1aaf..63e52dc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js @@ -26,3 +26,5 @@ var Input = Common.InputExpression var TokenType = TK.TokenType var Token = TK.Token var Tokenizer = TK.ExpressionTokenizer + +var FUNCTIONS_LIST = Reference.FUNCTIONS_LIST diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js index 9838446..81470f2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js @@ -64,6 +64,8 @@ const FUNCTIONS = { "tan": Math.tan, "tanh": Math.tanh, "trunc": Math.trunc, + "integral": () => 0, // TODO: Implement + "derivative": () => 0, } const FUNCTIONS_LIST = Object.keys(FUNCTIONS); // TODO: Complete diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js index 6d8e20b..67a2a41 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js @@ -41,9 +41,10 @@ var TokenType = { } class Token { - constructor(type, value) { + constructor(type, value, startPosition) { this.type = type; this.value = value; + this.startPosition = startPosition } } @@ -65,7 +66,7 @@ class ExpressionTokenizer { while(!this.input.atEnd() && WHITESPACES.includes(this.input.peek())) { included += this.input.next(); } - return new Token(TokenType.WHITESPACE, included) + return new Token(TokenType.WHITESPACE, included, this.input.position-included.length) } readString() { @@ -80,7 +81,7 @@ class ExpressionTokenizer { included += this.input.next(); } this.input.skip(delimitation) - let token = new Token(TokenType.STRING, included) + let token = new Token(TokenType.STRING, included, this.input.position-included.length) token.limitator = delimitation return token } else { @@ -98,7 +99,7 @@ class ExpressionTokenizer { } included += this.input.next(); } - return new Token(TokenType.NUMBER, included) + return new Token(TokenType.NUMBER, included, this.input.position-included.length) } readOperator() { @@ -106,7 +107,7 @@ class ExpressionTokenizer { while(!this.input.atEnd() && OPERATORS.includes(this.input.peek())) { included += this.input.next(); } - return new Token(TokenType.OPERATOR, included) + return new Token(TokenType.OPERATOR, included, this.input.position-included.length) } readIdentifier() { @@ -115,11 +116,11 @@ class ExpressionTokenizer { identifier += this.input.next(); } if(Reference.CONSTANTS_LIST.includes(identifier.toLowerCase())) { - return new Token(TokenType.CONSTANT, identifier.toLowerCase()) + return new Token(TokenType.CONSTANT, identifier.toLowerCase(), this.input.position-identifier.length) } else if(Reference.FUNCTIONS_LIST.includes(identifier.toLowerCase())) { - return new Token(TokenType.FUNCTION, identifier.toLowerCase()) + return new Token(TokenType.FUNCTION, identifier.toLowerCase(), this.input.position-identifier.length) } else { - return new Token(TokenType.VARIABLE, identifier) + return new Token(TokenType.VARIABLE, identifier, this.input.position-identifier.length) } } @@ -133,12 +134,12 @@ class ExpressionTokenizer { if(NUMBER_CHARS.includes(c)) return this.readNumber(); if(IDENTIFIER_CHARS.includes(c.toLowerCase())) return this.readIdentifier(); if(OPERATORS.includes(c)) return this.readOperator(); - if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, c); - if(PUNCTUTATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next()); + if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, this.input.next(), this.input.position-1); + if(PUNCTUTATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position-1); if(this.errorOnUnknown) this.input.throw("Unknown token character " + c) else - return new Token(TokenType.UNKNOWN, this.input.next()); + return new Token(TokenType.UNKNOWN, this.input.next(), this.input.position-1); } peek() { From 77ae54fa18f546f32949ef299917eb320a2d02f7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 00:37:02 +0200 Subject: [PATCH 054/436] More autocompletion! --- .../Setting/AutocompletionCategory.qml | 101 ++++++++++++++++++ .../Setting/ExpressionEditor.qml | 87 +++++++-------- .../eu/ad5001/LogarithmPlotter/Setting/qmldir | 1 + .../ad5001/LogarithmPlotter/js/math/common.js | 1 + .../ad5001/LogarithmPlotter/js/math/latex.js | 6 +- .../eu/ad5001/LogarithmPlotter/js/objects.js | 9 +- .../LogarithmPlotter/js/parsing/parsing.js | 1 + 7 files changed, 151 insertions(+), 55 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml new file mode 100644 index 0000000..77805fb --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -0,0 +1,101 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +/*! + \qmltype AutocompletionCategory + \inqmlmodule eu.ad5001.LogarithmPlotter.Setting + \brief ListView representing a category of autocompletion. + + \sa ExpressionEditor +*/ +ListView { + id: listFiltered + /*! + \qmlproperty int AutocompletionCategory::itemStartIndex + Start index of the first element in this list compared to the global autocompletion index. + */ + property int itemStartIndex: 0 + + /*! + \qmlproperty string AutocompletionCategory::category + Name of the category. + */ + property string category: "" + + /*! + \qmlproperty var AutocompletionCategory::categoryItems + List of items in this category. To be filtered by the autocomplete to filters. + */ + property var categoryItems: [] + + /*! + \qmlproperty var AutocompletionCategory::autocompleteGenerator + Javascript function taking the name of the item to create an autocompletion item (dictionary with + a 'text', 'autocomplete', and 'cursorFinalOffset' keys. + */ + property var autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item, 'cursorFinalOffset': 0}} + + /*! + \qmlproperty string AutocompletionCategory::baseText + Text to autocomplete. + */ + property string baseText: "" + width: parent.width + visible: model.length > 0 + implicitHeight: contentItem.childrenRect.height + headerItem.height + model: parent.visible ? categoryItems.filter((item) => item.includes(baseText)).map(autocompleteGenerator) : [] + + header: Column { + width: listFiltered.width + spacing: 2 + topPadding: 5 + bottomPadding: 5 + + Text { + leftPadding: 5 + text: listFiltered.category + } + + Rectangle { + height: 1 + color: 'black' + width: parent.width + } + } + + delegate: Rectangle { + property bool selected: index + listFiltered.itemStartIndex == acPopupContent.itemSelected + + width: autocompleteText.width + height: autocompleteText.height + color: selected ? sysPalette.highlight : 'transparent' + + Text { + id: autocompleteText + topPadding: 2 + bottomPadding: 2 + leftPadding: 15 + text: listFiltered.model[index].text + width: listFiltered.width + color: parent.selected ? sysPalette.highlightedText : sysPalette.windowText + } + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 6ab5f49..2450a1d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -22,6 +22,7 @@ import QtQuick.Dialogs 1.3 as D import eu.ad5001.LogarithmPlotter.Popup 1.0 as P import "../js/mathlib.js" as MathLib import "../js/utils.js" as Utils +import "../js/objects.js" as Objects import "../js/parsing/parsing.js" as Parsing @@ -30,7 +31,7 @@ import "../js/parsing/parsing.js" as Parsing \inqmlmodule eu.ad5001.LogarithmPlotter.Setting \brief Setting to edit strings and numbers. - \sa EditorDialog, Settings, Icon + \sa EditorDialog, AutocompletionCategory */ Item { id: control @@ -177,12 +178,18 @@ Item { } Keys.onUpPressed: function(event) { - acPopupContent.itemSelected = Math.max(0, acPopupContent.itemSelected-1) + if(acPopupContent.itemSelected == 0) + acPopupContent.itemSelected = acPopupContent.itemCount-1 + else + acPopupContent.itemSelected = acPopupContent.itemSelected-1 event.accepted = true } Keys.onDownPressed: function(event) { - acPopupContent.itemSelected = Math.max(0,Math.min(acPopupContent.itemCount-1, acPopupContent.itemSelected+1)) + if(acPopupContent.itemSelected == Math.min(acPopupContent.itemCount-1)) + acPopupContent.itemSelected = 0 + else + acPopupContent.itemSelected = acPopupContent.itemSelected+1 event.accepted = true } @@ -243,8 +250,8 @@ Item { visible: currentToken != null && identifierTokenTypes.includes(currentToken.type) // Focus handling. - readonly property var lists: [functionsList] - readonly property int itemCount: functionsList.model.length + readonly property var lists: [constantsList, functionsList, executableObjectList] + readonly property int itemCount: constantsList.model.length + functionsList.model.length + executableObjectList.model.length property int itemSelected: 0 /*! @@ -275,52 +282,34 @@ Item { editor.cursorPosition = startPos+autotext.autocomplete.length+autotext.cursorFinalOffset } - ListView { - id: functionsList - //anchors.fill: parent - property int itemStartIndex: 0 - width: parent.width - visible: model.length > 0 - implicitHeight: contentItem.childrenRect.height + headerItem.height - model: parent.visible ? - Parsing.FUNCTIONS_LIST.filter((name) => name.includes(acPopupContent.currentToken.value)) - .map((name) => {return {'text': name, 'autocomplete': name+'()', 'cursorFinalOffset': -1}}) : [] + AutocompletionCategory { + id: constantsList - header: Column { - width: functionsList.width - spacing: 2 - topPadding: 5 - bottomPadding: 5 - - Text { - leftPadding: 5 - text: qsTr("Functions") - } - - Rectangle { - height: 1 - color: 'black' - width: parent.width - } - } + itemStartIndex: 0 + category: qsTr("Constants") + categoryItems: Parsing.CONSTANTS_LIST + autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item + " ", 'cursorFinalOffset': 0}} + baseText: parent.currentToken.value + } - delegate: Rectangle { - property bool selected: index + functionsList.itemStartIndex == acPopupContent.itemSelected - - width: funcText.width - height: funcText.height - color: selected ? sysPalette.highlight : 'transparent' - - Text { - id: funcText - topPadding: 2 - bottomPadding: 2 - leftPadding: 15 - text: functionsList.model[index].text - width: functionsList.width - color: parent.selected ? sysPalette.highlightedText : sysPalette.windowText - } - } + AutocompletionCategory { + id: functionsList + + itemStartIndex: constantsList.model.length + category: qsTr("Functions") + categoryItems: Parsing.FUNCTIONS_LIST + autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item+'()', 'cursorFinalOffset': -1}} + baseText: parent.currentToken.value + } + + AutocompletionCategory { + id: executableObjectList + + itemStartIndex: constantsList.model.length + functionsList.model.length + category: qsTr("Executable Objects") + categoryItems: Objects.getObjectsName("ExecutableObject") + autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item+'()', 'cursorFinalOffset': -1}} + baseText: parent.currentToken.value } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir index d6e55e5..8106e26 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/qmldir @@ -5,3 +5,4 @@ Icon 1.0 Icon.qml ListSetting 1.0 ListSetting.qml TextSetting 1.0 TextSetting.qml ExpressionEditor 1.0 ExpressionEditor.qml +AutocompletionCategory 1.0 AutocompletionCategory.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 80f9402..156394b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -28,6 +28,7 @@ var evalVariables = { // Variables not provided by expr-eval.js, needs to be pro "pi": Math.PI, "π": Math.PI, "inf": Infinity, + "infinity": Infinity, "Infinity": Infinity, "∞": Infinity, "e": Math.E, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 06d0bfa..9ebdf6d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -148,9 +148,11 @@ function expression(tokens) { switch(type) { case ExprEval.INUMBER: - if (typeof item.value === 'number' && item.value < 0) { + if(item.value == Infinity) { + nstack.push("\\infty") + } else if(typeof item.value === 'number' && item.value < 0) { nstack.push(par(item.value)); - } else if (Array.isArray(item.value)) { + } else if(Array.isArray(item.value)) { nstack.push('[' + item.value.map(ExprEval.escapeValue).join(', ') + ']'); } else { nstack.push(ExprEval.escapeValue(item.value)); diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js index 9f3e972..5fc5d6a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js @@ -58,11 +58,12 @@ function getObjectsName(objType) { * @return {array} List of names of the objects. */ if(objType == "ExecutableObject") { - var types = getExecutableTypes() - var elementNames = [''] - types.forEach(function(elemType){ + // NOTE: QMLJS does not support flatMap. + // return getExecutableTypes().flatMap(elemType => currentObjects[elemType].map(obj => obj.name)) + let types = getExecutableTypes() + let elementNames = [''] + for(let elemType of types) elementNames = elementNames.concat(currentObjects[elemType].map(obj => obj.name)) - }) return elementNames } if(currentObjects[objType] == undefined) return [] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js index 63e52dc..6dfe932 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js @@ -28,3 +28,4 @@ var Token = TK.Token var Tokenizer = TK.ExpressionTokenizer var FUNCTIONS_LIST = Reference.FUNCTIONS_LIST +var CONSTANTS_LIST = Reference.CONSTANTS_LIST From 15b87fc15dd45847f7b91a4d9c3dd726b938e367 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 01:14:09 +0200 Subject: [PATCH 055/436] Variables & objects (+ their type) in autocompletion. --- .../ObjectLists/Editor/CustomPropertyList.qml | 3 +- .../Setting/AutocompletionCategory.qml | 28 ++++++-- .../Setting/ExpressionEditor.qml | 72 +++++++++++++++---- .../LogarithmPlotter/js/history/position.js | 2 +- .../ad5001/LogarithmPlotter/js/objs/common.js | 9 +-- .../LogarithmPlotter/js/objs/function.js | 2 +- .../LogarithmPlotter/js/objs/gainbode.js | 2 +- .../LogarithmPlotter/js/objs/phasebode.js | 2 +- .../ad5001/LogarithmPlotter/js/objs/point.js | 4 +- .../js/objs/sommegainsbode.js | 2 +- .../ad5001/LogarithmPlotter/js/objs/text.js | 4 +- .../ad5001/LogarithmPlotter/js/parameters.js | 7 ++ 12 files changed, 102 insertions(+), 35 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 42499a9..aa26594 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -74,6 +74,7 @@ Repeater { icon: `settings/custom/${propertyIcon}.svg` defValue: Utils.simplifyExpression(obj[propertyName].toEditableString()) self: obj.name + variables: propertyType.variables onChanged: function(newExpr) { if(obj[propertyName].toString() != newExpr.toString()) { history.addToHistory(new HistoryLib.EditedProperty( @@ -267,7 +268,7 @@ Repeater { return commentComponent else if(propertyType == 'boolean') return checkboxComponent - else if(propertyType == 'Expression') + else if(paramTypeIn(propertyType, ['Expression'])) return expressionEditorComponent else if(paramTypeIn(propertyType, textTypes)) return textEditorComponent diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index 77805fb..b0d2df9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -33,6 +33,11 @@ ListView { Start index of the first element in this list compared to the global autocompletion index. */ property int itemStartIndex: 0 + /*! + \qmlproperty int AutocompletionCategory::itemSelected + The global autocompletion index. + */ + property int itemSelected: 0 /*! \qmlproperty string AutocompletionCategory::category @@ -49,9 +54,9 @@ ListView { /*! \qmlproperty var AutocompletionCategory::autocompleteGenerator Javascript function taking the name of the item to create an autocompletion item (dictionary with - a 'text', 'autocomplete', and 'cursorFinalOffset' keys. + a 'text', 'annotation' 'autocomplete', and 'cursorFinalOffset' keys. */ - property var autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item, 'cursorFinalOffset': 0}} + property var autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item, 'annotation': '', 'cursorFinalOffset': 0}} /*! \qmlproperty string AutocompletionCategory::baseText @@ -60,7 +65,7 @@ ListView { property string baseText: "" width: parent.width visible: model.length > 0 - implicitHeight: contentItem.childrenRect.height + headerItem.height + implicitHeight: contentItem.childrenRect.height model: parent.visible ? categoryItems.filter((item) => item.includes(baseText)).map(autocompleteGenerator) : [] header: Column { @@ -82,10 +87,10 @@ ListView { } delegate: Rectangle { - property bool selected: index + listFiltered.itemStartIndex == acPopupContent.itemSelected + property bool selected: index + listFiltered.itemStartIndex == listFiltered.itemSelected - width: autocompleteText.width - height: autocompleteText.height + width: listFiltered.width + height: Math.max(autocompleteText.height, annotationText.height) color: selected ? sysPalette.highlight : 'transparent' Text { @@ -94,8 +99,17 @@ ListView { bottomPadding: 2 leftPadding: 15 text: listFiltered.model[index].text - width: listFiltered.width color: parent.selected ? sysPalette.highlightedText : sysPalette.windowText } + + Text { + id: annotationText + anchors.right: parent.right + topPadding: 2 + bottomPadding: 2 + rightPadding: 15 + text: listFiltered.model[index].annotation + color: parent.selected ? sysPaletteIn.highlightedText : sysPaletteIn.windowText + } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 2450a1d..c7b86c1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -61,6 +61,11 @@ Item { Used to prevent circular dependency. */ property string self: "" + /*! + \qmlproperty var ExpressionEditor::variables + Accepted variables for the expression. + */ + property var variables: [] /*! \qmlproperty string ExpressionEditor::placeholderText Value of the editor. @@ -250,8 +255,8 @@ Item { visible: currentToken != null && identifierTokenTypes.includes(currentToken.type) // Focus handling. - readonly property var lists: [constantsList, functionsList, executableObjectList] - readonly property int itemCount: constantsList.model.length + functionsList.model.length + executableObjectList.model.length + readonly property var lists: [variablesList, constantsList, functionsList, executableObjectsList, objectsList] + readonly property int itemCount: variablesList.model.length, constantsList.model.length + functionsList.model.length + executableObjectsList.model.length + objectsList.model.length property int itemSelected: 0 /*! @@ -276,40 +281,79 @@ Item { function autocomplete() { let autotext = autocompleteAt(itemSelected) let startPos = currentToken.startPosition - console.log("Autocompleting",autotext.text,startPos) editor.remove(startPos, startPos+currentToken.value.length) editor.insert(startPos, autotext.autocomplete) editor.cursorPosition = startPos+autotext.autocomplete.length+autotext.cursorFinalOffset } + AutocompletionCategory { + id: variablesList + + category: qsTr("Variables") + itemStartIndex: 0 + itemSelected: parent.itemSelected + categoryItems: control.variables + autocompleteGenerator: (item) => {return { + 'text': item, 'annotation': '', + 'autocomplete': item + " ", 'cursorFinalOffset': 0 + }} + baseText: parent.visible ? parent.currentToken.value : "" + } + AutocompletionCategory { id: constantsList - itemStartIndex: 0 category: qsTr("Constants") + itemStartIndex: variablesList.model.length + itemSelected: parent.itemSelected categoryItems: Parsing.CONSTANTS_LIST - autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item + " ", 'cursorFinalOffset': 0}} - baseText: parent.currentToken.value + autocompleteGenerator: (item) => {return { + 'text': item, 'annotation': '', + 'autocomplete': item + " ", 'cursorFinalOffset': 0 + }} + baseText: parent.visible ? parent.currentToken.value : "" } AutocompletionCategory { id: functionsList - itemStartIndex: constantsList.model.length category: qsTr("Functions") + itemStartIndex: variablesList.model.length + constantsList.model.length + itemSelected: parent.itemSelected categoryItems: Parsing.FUNCTIONS_LIST - autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item+'()', 'cursorFinalOffset': -1}} - baseText: parent.currentToken.value + autocompleteGenerator: (item) => {return { + 'text': item, 'annotation': '', + 'autocomplete': item+'()', 'cursorFinalOffset': -1 + }} + baseText: parent.visible ? parent.currentToken.value : "" } AutocompletionCategory { - id: executableObjectList + id: executableObjectsList - itemStartIndex: constantsList.model.length + functionsList.model.length category: qsTr("Executable Objects") - categoryItems: Objects.getObjectsName("ExecutableObject") - autocompleteGenerator: (item) => {return {'text': item, 'autocomplete': item+'()', 'cursorFinalOffset': -1}} - baseText: parent.currentToken.value + itemStartIndex: variablesList.model.length + constantsList.model.length + functionsList.model.length + itemSelected: parent.itemSelected + categoryItems: Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) + autocompleteGenerator: (item) => {return { + 'text': item, 'annotation': `${Objects.currentObjectsByName[item].constructor.displayType()}`, + 'autocomplete': item+'()', 'cursorFinalOffset': -1 + }} + baseText: parent.visible ? parent.currentToken.value : "" + } + + AutocompletionCategory { + id: objectsList + + category: qsTr("Objects") + itemStartIndex: executableObjectsList.model.length + variablesList.model.length + constantsList.model.length + functionsList.model.length + itemSelected: parent.itemSelected + categoryItems: Object.keys(Objects.currentObjectsByName).filter(obj => obj != self) + autocompleteGenerator: (item) => {return { + 'text': item, 'annotation': `${Objects.currentObjectsByName[item].constructor.displayType()}`, + 'autocomplete': item+'.', 'cursorFinalOffset': 0 + }} + baseText: parent.visible ? parent.currentToken.value : "" } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js index d33ad71..1a2ba46 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js @@ -75,7 +75,7 @@ class EditedPosition extends C.Action { } export() { - return [this.targetName, this.targetType, this.targetProperty, + return [this.targetName, this.targetType, this.previousXValue.toEditableString(), this.newXValue.toEditableString(), this.previousYValue.toEditableString(), this.newYValue.toEditableString()] } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 6c15ce5..907bf63 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -30,9 +30,10 @@ * Creates a new name for an object, based on the \c allowedLetters. * If variables with each of the allowedLetters is created, a subscript * number is added to the name. + * @param {string} prefix - Prefix to the name. * @return {string} New unused name for a new object. */ -function getNewName(allowedLetters) { +function getNewName(allowedLetters, prefix='') { // Allows to get a new name, based on the allowed letters, // as well as adding a sub number when needs be. var newid = 0 @@ -40,7 +41,7 @@ function getNewName(allowedLetters) { do { var letter = allowedLetters[newid % allowedLetters.length] var num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) - ret = letter + (num > 0 ? Utils.textsub(num-1) : '') + ret = prefix + letter + (num > 0 ? Utils.textsub(num-1) : '') newid += 1 } while(ret in Objects.currentObjectsByName) return ret @@ -80,10 +81,10 @@ class DrawableObject { * List of properties used in the Object Editor. * * Properties are set with key as property name and - * value as it's type name (e.g 'Expression', 'string'...), + * value as it's type name (e.g 'numbers', 'string'...), * an Enum for enumerations, an ObjectType for DrawableObjects * with a specific type, a List instance for lists, a - * Dictionary instance for dictionaries... + * Dictionary instance for dictionaries, an Expression for expressions... * * If the property is to be translated, the key should be passed * through the QT_TRANSLATE_NOOP macro in that form: diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index 746d880..85a798f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -30,7 +30,7 @@ class Function extends Common.ExecutableObject { static displayType(){return qsTr('Function')} static displayTypeMultiple(){return qsTr('Functions')} static properties() {return { - [QT_TRANSLATE_NOOP('prop','expression')]: 'Expression', + [QT_TRANSLATE_NOOP('prop','expression')]: new P.Expression('x'), [QT_TRANSLATE_NOOP('prop','definitionDomain')]: 'Domain', [QT_TRANSLATE_NOOP('prop','destinationDomain')]: 'Domain', 'comment1': QT_TRANSLATE_NOOP( diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index 72d583f..0130a9e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -35,7 +35,7 @@ class GainBode extends Common.ExecutableObject { static properties() {return { [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'), [QT_TRANSLATE_NOOP('prop','pass')]: P.Enum.BodePass, - [QT_TRANSLATE_NOOP('prop','gain')]: 'Expression', + [QT_TRANSLATE_NOOP('prop','gain')]: new P.Expression(), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', [QT_TRANSLATE_NOOP('prop','omGraduation')]: 'boolean' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index f8d2aaf..528910b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -32,7 +32,7 @@ class PhaseBode extends Common.ExecutableObject { static displayTypeMultiple(){return qsTr('Bode Phases')} static properties() {return { [QT_TRANSLATE_NOOP('prop','om_0')]: new P.ObjectType('Point'), - [QT_TRANSLATE_NOOP('prop','phase')]: 'Expression', + [QT_TRANSLATE_NOOP('prop','phase')]: new P.Expression(), [QT_TRANSLATE_NOOP('prop','unit')]: new P.Enum('°', 'deg', 'rad'), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelX')]: 'number' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js index 1f35192..760ab68 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js @@ -30,8 +30,8 @@ class Point extends Common.DrawableObject { static displayTypeMultiple(){return qsTr('Points')} static properties() {return { - [QT_TRANSLATE_NOOP('prop','x')]: 'Expression', - [QT_TRANSLATE_NOOP('prop','y')]: 'Expression', + [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), + [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','pointStyle')]: new P.Enum('●', '✕', '+') }} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js index 8f5854c..70e7440 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js @@ -26,7 +26,7 @@ .import "../math/latex.js" as Latex -class SommeGainsBode extends Common.DrawableObject { +class SommeGainsBode extends Common.ExecutableObject { static type(){return 'Somme gains Bode'} static displayType(){return qsTr('Bode Magnitudes Sum')} static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index 5d98e4e..99e9936 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -30,8 +30,8 @@ class Text extends Common.DrawableObject { static displayType(){return qsTr('Text')} static displayTypeMultiple(){return qsTr('Texts')} static properties() {return { - [QT_TRANSLATE_NOOP('prop','x')]: 'Expression', - [QT_TRANSLATE_NOOP('prop','y')]: 'Expression', + [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), + [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Positioning, [QT_TRANSLATE_NOOP('prop','text')]: 'string', 'comment1': QT_TRANSLATE_NOOP( diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js index 75309a8..1733a90 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js @@ -16,6 +16,13 @@ * along with this program. If not, see . */ +class Expression { + constructor(...variables) { + this.type = 'Expression' + this.variables = variables + } +} + class Enum { constructor(...values) { this.type = 'Enum' From 7f548796f2cb4d3ccf6e23fb995ffe5baed923e3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 01:25:55 +0200 Subject: [PATCH 056/436] Slight change for Repartition for the name to be prefixed by F_ on creation. This makes it better when using it in tooltips for autocompletion. --- .../ObjectLists/Editor/CustomPropertyList.qml | 4 ++-- .../LogarithmPlotter/js/objs/repartition.js | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index aa26594..18da95f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -231,8 +231,8 @@ Repeater { dictionaryMode: paramTypeIn(propertyType, ['Dict']) keyType: dictionaryMode ? propertyType.keyType : 'string' valueType: propertyType.valueType - preKeyLabel: (dictionaryMode ? propertyType.preKeyLabel : propertyType.label).replace(/\{name\}/g, obj.name) - postKeyLabel: (dictionaryMode ? propertyType.postKeyLabel : '').replace(/\{name\}/g, obj.name) + preKeyLabel: (dictionaryMode ? propertyType.preKeyLabel : propertyType.label).replace(/\{name\}/g, obj.name).replace(/\{name_\}/g, obj.name.substring(obj.name.indexOf("_")+1)) + postKeyLabel: (dictionaryMode ? propertyType.postKeyLabel : '').replace(/\{name\}/g, obj.name).replace(/\{name_\}/g, obj.name.substring(obj.name.indexOf("_")+1)) keyRegexp: dictionaryMode ? propertyType.keyFormat : /^.+$/ valueRegexp: propertyType.format forbidAdding: propertyType.forbidAdding diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js index 0f25c4c..dc20a73 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js @@ -34,12 +34,12 @@ class RepartitionFunction extends Common.ExecutableObject { 'comment', 'Note: Specify the probability for each value.' ), - [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d\.,]+$/, 'P({name} = ', ') = '), + [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d\.,]+$/, 'P({name_} = ', ') = '), }} constructor(name = null, visible = true, color = null, labelContent = 'name + value', beginIncluded = true, drawLineEnds = true, probabilities = {'0': '0'}, labelPosition = 'above', labelX = 1) { - if(name == null) name = Common.getNewName('XYZUVW') + if(name == null) name = Common.getNewName('XYZUVW', "F_") super(name, visible, color, labelContent) this.beginIncluded = beginIncluded this.drawLineEnds = drawLineEnds @@ -56,14 +56,16 @@ class RepartitionFunction extends Common.ExecutableObject { getReadableString() { - var keys = Object.keys(this.probabilities).sort((a,b) => a-b); - return `F_${this.name}(x) = P(${this.name} ≤ x)\n` + keys.map(idx => `P(${this.name}=${idx})=${this.probabilities[idx]}`).join("; ") + let keys = Object.keys(this.probabilities).sort((a,b) => a-b); + let varname = this.name.substring(this.name.indexOf("_")+1) + return `${this.name}(x) = P(${varname} ≤ x)\n` + keys.map(idx => `P(${varname}=${idx})=${this.probabilities[idx]}`).join("; ") } getLatexString() { let keys = Object.keys(this.probabilities).sort((a,b) => a-b); - let varName = Latex.variable(this.name) - return `\\begin{array}{l}F_{${varName}}(x) = P(${varName} \\le x)\\\\` + keys.map(idx => `P(${varName}=${idx})=${this.probabilities[idx]}`).join("; ") + '\\end{array}' + let funcName = Latex.variable(this.name) + let varName = Latex.variable(this.name.substring(this.name.indexOf("_")+1)) + return `\\begin{array}{l}{${funcName}}(x) = P(${varName} \\le x)\\\\` + keys.map(idx => `P(${varName}=${idx})=${this.probabilities[idx]}`).join("; ") + '\\end{array}' } execute(x = 1) { @@ -83,7 +85,7 @@ class RepartitionFunction extends Common.ExecutableObject { getLabel() { switch(this.labelContent) { case 'name': - return `P(${this.name} ≤ x)` + return `${this.name}(x)` case 'name + value': return this.getReadableString() case 'null': From 47a9f63d66c00f6cdca6785d2224ffcc565f0efe Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 01:35:14 +0200 Subject: [PATCH 057/436] Adding new category for object properties unpopulated Adding new translations --- LogarithmPlotter/i18n/lp_de.ts | 117 +++++++++++------- LogarithmPlotter/i18n/lp_en.ts | 117 +++++++++++------- LogarithmPlotter/i18n/lp_es.ts | 117 +++++++++++------- LogarithmPlotter/i18n/lp_fr.ts | 117 +++++++++++------- LogarithmPlotter/i18n/lp_hu.ts | 117 +++++++++++------- LogarithmPlotter/i18n/lp_nb_NO.ts | 117 +++++++++++------- LogarithmPlotter/i18n/lp_template.ts | 117 +++++++++++------- .../Setting/ExpressionEditor.qml | 29 +++-- 8 files changed, 547 insertions(+), 301 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 6883254..0beb08c 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -169,8 +169,8 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen @@ -178,42 +178,42 @@ Dialog - + Edit properties of %1 %2 Eigenschaften von %1 %2 bearbeiten - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ungültiger Objektname - + An object with the name '%1' already exists. Ein Objekt mit dem Namen '%1' existiert bereits. - + Name Name - + Label content Etikett - + null leer - + name Name - + name + value Name + Wert @@ -249,6 +249,39 @@ + Neues %1objekt erstellen + + ExpressionEditor + + + Object Properties + + + + + Variables + + + + + Constants + + + + + Functions + Funktionen + + + + Executable Objects + + + + + Objects + Objekte + + FileDialog @@ -734,7 +767,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - + %1: @@ -762,12 +795,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 von %2 %3 wurde von "%4" auf "%5" geändert. - + %1 of %2 changed from %3 to %4. %1 von %2 wurde von %3 auf %4 geändert. @@ -900,17 +933,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. @@ -918,12 +951,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler - + Error while parsing expression for property %1: %2 @@ -1052,114 +1085,114 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde parameters - + above ↑ Über - + below ↓ Unter - - + + left ← Links - - + + right → Rechts - + above-left ↖ Oben links - + above-right ↗ Oben rechts - + below-left ↙ Unten links - + below-right ↘ Unten rechts - + center >|< Zentrum - + top ↑ Über - + bottom ↓ Unter - + top-left ↖ Oben links - + top-right ↗ Oben rechts - + bottom-left ↙ Unten links - + bottom-right ↘ Unten rechts - + application Anwendung - + function Funktion - + high Hoch - + low Tief - + Next to target Neben dem Ziel - + With label Mit Etikett - + Hidden Versteckt diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index e78a4a5..16cb0e7 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -169,8 +169,8 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 @@ -178,42 +178,42 @@ Dialog - + Edit properties of %1 %2 Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. An object with the name '%1' already exists. - + Name Name - + Label content Label content - + null null - + name name - + name + value name + value @@ -249,6 +249,39 @@ + Create new %1 + + ExpressionEditor + + + Object Properties + + + + + Variables + + + + + Constants + + + + + Functions + Functions + + + + Executable Objects + + + + + Objects + Objects + + FileDialog @@ -734,7 +767,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -762,12 +795,12 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. %1 of %2 changed from %3 to %4. @@ -900,17 +933,17 @@ These settings can be changed at any time from the "Settings" menu.End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. @@ -918,12 +951,12 @@ These settings can be changed at any time from the "Settings" menu. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1052,114 +1085,114 @@ Please make sure your LaTeX installation is correct and report a bug if so. parameters - + above ↑ Above - + below ↓ Below - - + + left ← Left - - + + right → Right - + above-left ↖ Above left - + above-right ↗ Above right - + below-left ↙ Below left - + below-right ↘ Below right - + center >|< Center - + top ↑ Top - + bottom ↓ Bottom - + top-left ↖ Top left - + top-right ↗ Top right - + bottom-left ↙ Bottom left - + bottom-right ↘ Bottom right - + application Application - + function Function - + high High - + low Low - + Next to target Next to target - + With label With label - + Hidden Hidden diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index dfaf15b..992dd8c 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -169,8 +169,8 @@ CustomPropertyList - - + + + Create new %1 @@ -178,46 +178,79 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value + + ExpressionEditor + + + Object Properties + + + + + Variables + + + + + Constants + + + + + Functions + + + + + Executable Objects + + + + + Objects + + + FileDialog @@ -682,7 +715,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -710,12 +743,12 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. @@ -848,17 +881,17 @@ These settings can be changed at any time from the "Settings" menu. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. @@ -866,12 +899,12 @@ These settings can be changed at any time from the "Settings" menu. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -961,114 +994,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - + below - - + + left - - + + right - + above-left - + above-right - + below-left - + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index c6dbf1f..6e84cc6 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -170,8 +170,8 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 @@ -179,42 +179,42 @@ Dialog - + Edit properties of %1 %2 Changer les propriétés de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nom d'objet invalide - + An object with the name '%1' already exists. Un objet portant le nom '%1' existe déjà. - + Name Nom - + Label content Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -251,6 +251,39 @@ + Créer un nouvel objet %1 + + ExpressionEditor + + + Object Properties + + + + + Variables + + + + + Constants + + + + + Functions + Fonctions + + + + Executable Objects + + + + + Objects + Objets + + FileDialog @@ -743,7 +776,7 @@ These settings can always be changed at any time from the "Settings" m - + %1: @@ -771,12 +804,12 @@ These settings can always be changed at any time from the "Settings" m editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 modifiée de "%4" à "%5". - + %1 of %2 changed from %3 to %4. %1 de %2 modifiée de %3 à %4. @@ -909,17 +942,17 @@ These settings can always be changed at any time from the "Settings" m Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. @@ -927,12 +960,12 @@ These settings can always be changed at any time from the "Settings" m expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe - + Error while parsing expression for property %1: %2 @@ -1061,114 +1094,114 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c parameters - + above ↑ Au dessus - + below ↓ En dessous - - + + left ← À gauche - - + + right → À droite - + above-left ↖ Au dessus à gauche - + above-right ↗ Au dessus à droite - + below-left ↙ En dessous à gauche - + below-right ↘ En dessous à droite - + center >|< Centré - + top ↑ Au dessus - + bottom ↓ En dessous - + top-left ↖ Au dessus à gauche - + top-right ↗ Au dessus à droite - + bottom-left ↙ En dessous à gauche - + bottom-right ↘ En dessous à droite - + application Application - + function Fonction - + high Haut - + low Bas - + Next to target A côté de la cible - + With label Avec l'étiquette - + Hidden Caché diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index a2c2163..45bcef3 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -169,8 +169,8 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása @@ -178,42 +178,42 @@ Dialog - + Edit properties of %1 %2 %1 %2 tulajdonságainak szerkesztése - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name Név - + Label content Címke tartalom - + null üres - + name név - + name + value név + érték @@ -249,6 +249,39 @@ + Új %1 létrehozása + + ExpressionEditor + + + Object Properties + + + + + Variables + + + + + Constants + + + + + Functions + Függvények + + + + Executable Objects + + + + + Objects + Tárgyak + + FileDialog @@ -734,7 +767,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + %1: @@ -762,12 +795,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. - + %1 of %2 changed from %3 to %4. %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -900,17 +933,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. @@ -918,12 +951,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1045,114 +1078,114 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents parameters - + above ↑ Felett - + below ↓ Alatt - - + + left ← Balra - - + + right → Jobbra - + above-left ↖ Felett, balra - + above-right ↗ Felett, jobbra - + below-left ↙ Alatt, balra - + below-right ↘ Alatt, jobbra - + center >|< Középre - + top ↑ Felső - + bottom ↓ Alsó - + top-left ↖ Bal felső - + top-right ↗ Jobb felső - + bottom-left ↙ Bal alsó - + bottom-right ↘ Jobb alsó - + application Alkalmazás - + function Függvény - + high Magas - + low Alul - + Next to target Cél mellé - + With label Címkével - + Hidden Rejtett diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index dfdfd34..d1becca 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -169,8 +169,8 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 @@ -178,42 +178,42 @@ Dialog - + Edit properties of %1 %2 Rediger egenskaper for %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name Navn - + Label content Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -249,6 +249,39 @@ + Opprett nytt %1 + + ExpressionEditor + + + Object Properties + + + + + Variables + + + + + Constants + + + + + Functions + Funksjoner + + + + Executable Objects + + + + + Objects + Objekter + + FileDialog @@ -734,7 +767,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + %1: @@ -762,12 +795,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 av %2 %3 endret fra «%4» til «%5». - + %1 of %2 changed from %3 to %4. @@ -900,17 +933,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. @@ -918,12 +951,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1036,114 +1069,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - + below - - + + left - - + + right - + above-left - + above-right - + below-left - + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index f525586..377be41 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -169,8 +169,8 @@ CustomPropertyList - - + + + Create new %1 @@ -178,46 +178,79 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value + + ExpressionEditor + + + Object Properties + + + + + Variables + + + + + Constants + + + + + Functions + + + + + Executable Objects + + + + + Objects + + + FileDialog @@ -682,7 +715,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -710,12 +743,12 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. @@ -848,17 +881,17 @@ These settings can be changed at any time from the "Settings" menu. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. @@ -866,12 +899,12 @@ These settings can be changed at any time from the "Settings" menu. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -961,114 +994,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - + below - - + + left - - + + right - + above-left - + above-right - + below-left - + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index c7b86c1..578ac20 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -255,8 +255,8 @@ Item { visible: currentToken != null && identifierTokenTypes.includes(currentToken.type) // Focus handling. - readonly property var lists: [variablesList, constantsList, functionsList, executableObjectsList, objectsList] - readonly property int itemCount: variablesList.model.length, constantsList.model.length + functionsList.model.length + executableObjectsList.model.length + objectsList.model.length + readonly property var lists: [objectPropertiesList, variablesList, constantsList, functionsList, executableObjectsList, objectsList] + readonly property int itemCount: objectPropertiesList.model.length + variablesList.model.length, constantsList.model.length + functionsList.model.length + executableObjectsList.model.length + objectsList.model.length property int itemSelected: 0 /*! @@ -286,11 +286,26 @@ Item { editor.cursorPosition = startPos+autotext.autocomplete.length+autotext.cursorFinalOffset } + AutocompletionCategory { + id: objectPropertiesList + + category: qsTr("Object Properties") + itemStartIndex: 0 + itemSelected: parent.itemSelected + categoryItems: [] + property var objectName: null + autocompleteGenerator: (item) => {return { + 'text': item, 'annotation': Objects.currentObjectsByName[objectName].constructor.properties()[item], + 'autocomplete': item + " ", 'cursorFinalOffset': 0 + }} + baseText: parent.visible ? parent.currentToken.value : "" + } + AutocompletionCategory { id: variablesList category: qsTr("Variables") - itemStartIndex: 0 + itemStartIndex: objectPropertiesList.model.length itemSelected: parent.itemSelected categoryItems: control.variables autocompleteGenerator: (item) => {return { @@ -304,7 +319,7 @@ Item { id: constantsList category: qsTr("Constants") - itemStartIndex: variablesList.model.length + itemStartIndex: variablesList.itemStartIndex + variablesList.model.length itemSelected: parent.itemSelected categoryItems: Parsing.CONSTANTS_LIST autocompleteGenerator: (item) => {return { @@ -318,7 +333,7 @@ Item { id: functionsList category: qsTr("Functions") - itemStartIndex: variablesList.model.length + constantsList.model.length + itemStartIndex: constantsList.itemStartIndex + constantsList.model.length itemSelected: parent.itemSelected categoryItems: Parsing.FUNCTIONS_LIST autocompleteGenerator: (item) => {return { @@ -332,7 +347,7 @@ Item { id: executableObjectsList category: qsTr("Executable Objects") - itemStartIndex: variablesList.model.length + constantsList.model.length + functionsList.model.length + itemStartIndex: functionsList.itemStartIndex + functionsList.model.length itemSelected: parent.itemSelected categoryItems: Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) autocompleteGenerator: (item) => {return { @@ -346,7 +361,7 @@ Item { id: objectsList category: qsTr("Objects") - itemStartIndex: executableObjectsList.model.length + variablesList.model.length + constantsList.model.length + functionsList.model.length + itemStartIndex: executableObjectsList.itemStartIndex + executableObjectsList.model.length itemSelected: parent.itemSelected categoryItems: Object.keys(Objects.currentObjectsByName).filter(obj => obj != self) autocompleteGenerator: (item) => {return { From 0561782293951323d63b5a3d51870a68526d3759 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 23:35:53 +0000 Subject: [PATCH 058/436] Translated using Weblate (English) Currently translated at 100.0% (244 of 244 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 16cb0e7..14ab20f 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -254,32 +254,32 @@ Object Properties - + Object Properties Variables - + Variables Constants - + Constants Functions - Functions + Functions Executable Objects - + Function Objects Objects - Objects + Objects From fc68d3da6a92c2f664f65b04c1ab62b49c0deb44 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 23:43:28 +0000 Subject: [PATCH 059/436] Translated using Weblate (German) Currently translated at 100.0% (244 of 244 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 0beb08c..c4e503e 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -254,32 +254,32 @@ Object Properties - + Objekteigenschaften Variables - + Variablen Constants - + Konstanten Functions - Funktionen + Funktion Executable Objects - + Funktionsobjekte Objects - Objekte + Objekte From 0e41c12e039d96dc11993858b48e0817aecf8333 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 19 Oct 2022 23:37:11 +0000 Subject: [PATCH 060/436] Translated using Weblate (French) Currently translated at 100.0% (244 of 244 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 6e84cc6..fdb96bd 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -256,32 +256,32 @@ Object Properties - + Propriétés de l'objet Variables - + Variables Constants - + Constantes Functions - Fonctions + Fonctions Executable Objects - + Objets fonction Objects - Objets + Objets From 3cd4ad6a20f8187c7cc2d7e8403689c4f2550463 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 16:23:12 +0200 Subject: [PATCH 061/436] Object properties for autocompletion! --- .../LogarithmPlotter/PickLocationOverlay.qml | 8 +- .../Setting/AutocompletionCategory.qml | 9 +- .../Setting/ExpressionEditor.qml | 86 +++++++++++++++---- .../ad5001/LogarithmPlotter/js/parameters.js | 20 +++++ .../LogarithmPlotter/js/parsing/tokenizer.js | 4 +- 5 files changed, 104 insertions(+), 23 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 7e59fd5..5460160 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -214,9 +214,9 @@ Item { Parses a given \c value as an expression or a number depending on the type of \c propertyName of all \c objType. */ function parseValue(value, objType, propertyName) { - return { - 'Expression': () => new MathLib.Expression(value), - 'number': () => parseFloat(value) - }[Objects.types[objType].properties()[propertyName]]() + if(Objects.types[objType].properties()[propertyName] == 'number') + return parseFloat(value) + else + return new MathLib.Expression(value) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index b0d2df9..7e9f683 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -63,10 +63,17 @@ ListView { Text to autocomplete. */ property string baseText: "" + + /*! + \qmlproperty bool AutocompletionCategory::visbilityCondition + Condition to be met for the category to be visible. + */ + property bool visbilityCondition: true + width: parent.width visible: model.length > 0 implicitHeight: contentItem.childrenRect.height - model: parent.visible ? categoryItems.filter((item) => item.includes(baseText)).map(autocompleteGenerator) : [] + model: visbilityCondition ? categoryItems.filter((item) => item.includes(baseText)).map(autocompleteGenerator) : [] header: Column { width: listFiltered.width diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 578ac20..87c3885 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -200,7 +200,8 @@ Item { Keys.onPressed: function(event) { // Autocomplete popup events - //console.log("Pressed key:", event.key, Qt.Key_Return, Qt.Key_Enter, event.text) + //console.log(acPopupContent.currentToken.dot, acPopupContent.previousToken.dot, "@", acPopupContent.currentToken.identifier, acPopupContent.previousToken.identifier, acPopupContent.previousToken2.identifier, objectPropertiesList.objectName, JSON.stringify(objectPropertiesList.baseText), objectPropertiesList.model.length, JSON.stringify(objectPropertiesList.categoryItems)) + //console.log("Pressed key:", event.key, Qt.Key_Return, Qt.Key_Enter, event.text, acPopupContent.itemCount) if((event.key == Qt.Key_Enter || event.key == Qt.Key_Return) && acPopupContent.itemCount > 0) { acPopupContent.autocomplete() event.accepted = true @@ -251,21 +252,40 @@ Item { Parsing.TokenType.FUNCTION, Parsing.TokenType.CONSTANT ] - property var currentToken: getTokenAt(editor.tokens, editor.cursorPosition) - visible: currentToken != null && identifierTokenTypes.includes(currentToken.type) + property var currentToken: generateTokenInformation(getTokenAt(editor.tokens, editor.cursorPosition)) + property var previousToken: generateTokenInformation(getPreviousToken(currentToken.token)) + property var previousToken2: generateTokenInformation(getPreviousToken(previousToken.token)) + property var previousToken3: generateTokenInformation(getPreviousToken(previousToken2.token)) + visible: currentToken.exists // Focus handling. readonly property var lists: [objectPropertiesList, variablesList, constantsList, functionsList, executableObjectsList, objectsList] - readonly property int itemCount: objectPropertiesList.model.length + variablesList.model.length, constantsList.model.length + functionsList.model.length + executableObjectsList.model.length + objectsList.model.length + readonly property int itemCount: objectPropertiesList.model.length + variablesList.model.length + constantsList.model.length + functionsList.model.length + executableObjectsList.model.length + objectsList.model.length property int itemSelected: 0 /*! - \qmlmethod var ExpressionEditor::autocompleteAt(int idx) + \qmlmethod var ExpressionEditor::generateTokenInformation(var token) + Generates basic information about the given token (existence and type) used in autocompletion). + */ + function generateTokenInformation(token) { + let exists = token != null + return { + 'token': token, + 'exists': exists, + 'value': exists ? token.value : null, + 'type': exists ? token.type : null, + 'startPosition': exists ? token.startPosition : 0, + 'dot': exists ? (token.type == Parsing.TokenType.PUNCT && token.value == ".") : false, + 'identifier': exists ? identifierTokenTypes.includes(token.type) : false + } + } + /*! + \qmlmethod void ExpressionEditor::autocompleteInfoAt(int idx) Returns the autocompletion text information at a given position. The information contains key 'text' (description text), 'autocomplete' (text to insert) and 'cursorFinalOffset' (amount to add to the cursor's position after the end of the autocomplete) */ - function autocompleteAt(idx) { + function autocompleteInfoAt(idx) { if(idx >= itemCount) return "" let startIndex = 0 for(let list of lists) { @@ -274,37 +294,67 @@ Item { startIndex += list.model.length } } + /*! - \qmlmethod var ExpressionEditor::autocomplete() + \qmlmethod void ExpressionEditor::autocomplete() Autocompletes with the current selected word. */ function autocomplete() { - let autotext = autocompleteAt(itemSelected) + let autotext = autocompleteInfoAt(itemSelected) let startPos = currentToken.startPosition + console.log("Replacing", currentToken.value, "at", startPos, "with", autotext.autocomplete) editor.remove(startPos, startPos+currentToken.value.length) editor.insert(startPos, autotext.autocomplete) editor.cursorPosition = startPos+autotext.autocomplete.length+autotext.cursorFinalOffset } + /*! + \qmlmethod var ExpressionEditor::getPreviousToken(var token) + Returns the token before this one. + */ + function getPreviousToken(token) { + let newToken = getTokenAt(editor.tokens, token.startPosition) + if(newToken != null && newToken.type == Parsing.TokenType.WHITESPACE) + return getPreviousToken(newToken) + return newToken + } + AutocompletionCategory { id: objectPropertiesList category: qsTr("Object Properties") + visbilityCondition: isEnteringProperty itemStartIndex: 0 itemSelected: parent.itemSelected - categoryItems: [] - property var objectName: null - autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': Objects.currentObjectsByName[objectName].constructor.properties()[item], - 'autocomplete': item + " ", 'cursorFinalOffset': 0 - }} - baseText: parent.visible ? parent.currentToken.value : "" + property bool isEnteringProperty: ( + // Current token is dot. + (parent.currentToken.dot && parent.previousToken.identifier && !parent.previousToken2.dot) || + // Current token is property identifier + (parent.currentToken.identifier && parent.previousToken.dot && parent.previousToken2.identifier && !parent.previousToken3.dot)) + property string objectName: isEnteringProperty ? + (parent.currentToken.dot ? parent.previousToken.value : parent.previousToken2.value) + : "" + property var objectProperties: isEnteringProperty ? + Objects.currentObjectsByName[objectName].constructor.properties() : + {} + categoryItems: Object.keys(objectProperties) + autocompleteGenerator: (item) => { + let propType = objectProperties[item] + return { + 'text': item, 'annotation': propType == null ? '' : propType.toString(), + 'autocomplete': parent.currentToken.dot ? `.${item} ` : `${item} `, + 'cursorFinalOffset': 0 + } + + } + baseText: parent.visible && !parent.currentToken.dot ? parent.currentToken.value : "" } AutocompletionCategory { id: variablesList category: qsTr("Variables") + visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: objectPropertiesList.model.length itemSelected: parent.itemSelected categoryItems: control.variables @@ -319,6 +369,7 @@ Item { id: constantsList category: qsTr("Constants") + visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: variablesList.itemStartIndex + variablesList.model.length itemSelected: parent.itemSelected categoryItems: Parsing.CONSTANTS_LIST @@ -333,6 +384,7 @@ Item { id: functionsList category: qsTr("Functions") + visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: constantsList.itemStartIndex + constantsList.model.length itemSelected: parent.itemSelected categoryItems: Parsing.FUNCTIONS_LIST @@ -347,11 +399,12 @@ Item { id: executableObjectsList category: qsTr("Executable Objects") + visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: functionsList.itemStartIndex + functionsList.model.length itemSelected: parent.itemSelected categoryItems: Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': `${Objects.currentObjectsByName[item].constructor.displayType()}`, + 'text': item, 'annotation': Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), 'autocomplete': item+'()', 'cursorFinalOffset': -1 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -361,6 +414,7 @@ Item { id: objectsList category: qsTr("Objects") + visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: executableObjectsList.itemStartIndex + executableObjectsList.model.length itemSelected: parent.itemSelected categoryItems: Object.keys(Objects.currentObjectsByName).filter(obj => obj != self) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js index 1733a90..c8d34ca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js @@ -21,6 +21,10 @@ class Expression { this.type = 'Expression' this.variables = variables } + + toString() { + return this.variables.length == 0 ? 'Number' : `Expression(${this.variables.join(', ')})` + } } class Enum { @@ -29,6 +33,10 @@ class Enum { this.values = values this.translatedValues = values.map(x => qsTr(x)) } + + toString() { + return this.type + } } class ObjectType { @@ -36,6 +44,10 @@ class ObjectType { this.type = 'ObjectType' this.objType = objType } + + toString() { + return this.objType + } } class List { @@ -47,6 +59,10 @@ class List { this.label = label this.forbidAdding = forbidAdding } + + toString() { + return this.objType + } } class Dictionary { @@ -61,6 +77,10 @@ class Dictionary { this.postKeyLabel = postKeyLabel this.forbidAdding = forbidAdding } + + toString() { + return 'Dictionary' + } } // Common parameters for Enums diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js index 67a2a41..63358c0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js @@ -24,7 +24,7 @@ const WHITESPACES = " \t\n\r" const STRING_LIMITORS = '"\'`'; const OPERATORS = "+-*/^%?:=!><"; const PUNCTUTATION = "()[]{},."; -const NUMBER_CHARS = "0123456789." +const NUMBER_CHARS = "0123456789" const IDENTIFIER_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_₀₁₂₃₄₅₆₇₈₉αβγδεζηθκλμξρςστφχψωₐₑₒₓₔₕₖₗₘₙₚₛₜ" var TokenType = { @@ -92,7 +92,7 @@ class ExpressionTokenizer { readNumber() { let included = ""; let hasDot = false; - while(!this.input.atEnd() && NUMBER_CHARS.includes(this.input.peek())) { + while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() == '.')) { if(this.input.peek() == ".") { if(hasDot) this.input.raise("Unexpected '.'. Expected digit") hasDot = true; From 7e427e5bb98a7a5bfc36ff402aa3c31602e2cdc1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 16:44:11 +0200 Subject: [PATCH 062/436] Fixing history rendering of expressions --- .../eu/ad5001/LogarithmPlotter/js/history/editproperty.js | 8 ++++++-- .../qml/eu/ad5001/LogarithmPlotter/js/math/expression.js | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js index b2862a2..17cc28f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js @@ -42,7 +42,7 @@ class EditedProperty extends C.Action { this.newValue = newValue this.propertyType = Objects.types[targetType].properties()[targetProperty] if(valueIsExpressionNeedingImport) { - if(this.propertyType == "Expression") { + if(typeof this.propertyType == 'object' && this.propertyType.type == "Expression") { this.previousValue = new MathLib.Expression(this.previousValue); this.newValue = new MathLib.Expression(this.newValue); } else if(this.propertyType == "Domain") { @@ -98,6 +98,10 @@ class EditedProperty extends C.Action { this.prevString = JSON.stringify(this.previousValue) this.nextString = JSON.stringify(this.newValue) break; + case "Expression": + this.prevString = this.previousValue == null ? "null" : this.previousValue.toString() + this.nextString = this.newValue == null ? "null" : this.newValue.toString() + break; } } else { this.prevString = this.previousValue == null ? "null" : this.previousValue.toString() @@ -106,7 +110,7 @@ class EditedProperty extends C.Action { // HTML this.prevHTML = ' '+this.prevString+' ' this.nextHTML = ' '+this.nextString+' ' - if(Latex.enabled && this.propertyType == "Expression") { + 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) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index a9b008a..9993152 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -63,7 +63,6 @@ class Expression { return this.cachedValue } C.currentVars = Object.assign({'x': x}, C.currentObjectsByName) - //console.log("Executing", this.expr, "with", JSON.stringify(C.currentVars)) return this.calc.evaluate(C.currentVars) } From 356169c749d6c9b4522c0044177d5e2dae88310e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 17:39:36 +0200 Subject: [PATCH 063/436] Fixing expression being set even if errors are found. --- .../eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 87c3885..9ca2878 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -475,12 +475,13 @@ Item { } if(expr.requiredObjects().includes(control.self)) throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) - // TODO: Check for recursive dependencies. + // TODO: Check for recursive dependencies. + return expr } catch(e) { // Error in expression parsingErrorDialog.showDialog(propertyName, newExpression, e.message) + return null } - return expr } /*! From 7241add9e55400faac097176c19b17eb45275919 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 18:10:49 +0200 Subject: [PATCH 064/436] Recursive dependencies & fixing some bugs related to dependencies themselves. --- LogarithmPlotter/i18n/lp_de.ts | 132 ++++++++++-------- LogarithmPlotter/i18n/lp_en.ts | 132 ++++++++++-------- LogarithmPlotter/i18n/lp_es.ts | 132 ++++++++++-------- LogarithmPlotter/i18n/lp_fr.ts | 132 ++++++++++-------- LogarithmPlotter/i18n/lp_hu.ts | 132 ++++++++++-------- LogarithmPlotter/i18n/lp_nb_NO.ts | 132 ++++++++++-------- LogarithmPlotter/i18n/lp_template.ts | 132 ++++++++++-------- .../Setting/ExpressionEditor.qml | 11 +- .../ad5001/LogarithmPlotter/js/expr-eval.js | 7 +- .../ad5001/LogarithmPlotter/js/objs/common.js | 43 +++--- 10 files changed, 539 insertions(+), 446 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index c4e503e..6b28082 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -252,32 +252,32 @@ ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktion - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -795,12 +795,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 von %2 %3 wurde von "%4" auf "%5" geändert. - + %1 of %2 changed from %3 to %4. %1 von %2 wurde von %3 auf %4 geändert. @@ -809,7 +809,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. @@ -824,129 +824,139 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). - + Unknown character "%1". Unbekanntes Schriftzeichen "%1". - - + + Illegal escape sequence: %1. Unzulässige Escapesequenz: %1. - - + + Parse error [%1:%2]: %3 Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 - + Function definition is not permitted. Funktionsdefinition ist nicht erlaubt. - + Expected variable for assignment. Erwartete Variable für Zuweisung. - + Unexpected ".": member access is not permitted Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt - + Unexpected "[]": arrays are disabled. Unerwartetes "[]": Arrays sind deaktiviert. - + Unexpected symbol: %1. Unerwartetes Symbol: %1. - + First argument to map is not a function. Der erste Parameter von map ist keine Formel. - + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. + + + Circular dependency detected. Object %1 depends on %2. + + + + + Circular dependency detected. Objects %1 depend on %2. + + expression @@ -1085,114 +1095,114 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde parameters - + above ↑ Über - + below ↓ Unter - - + + left ← Links - - + + right → Rechts - + above-left ↖ Oben links - + above-right ↗ Oben rechts - + below-left ↙ Unten links - + below-right ↘ Unten rechts - + center >|< Zentrum - + top ↑ Über - + bottom ↓ Unter - + top-left ↖ Oben links - + top-right ↗ Oben rechts - + bottom-left ↙ Unten links - + bottom-right ↘ Unten rechts - + application Anwendung - + function Funktion - + high Hoch - + low Tief - + Next to target Neben dem Ziel - + With label Mit Etikett - + Hidden Versteckt diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 14ab20f..9471a63 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -252,32 +252,32 @@ ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -795,12 +795,12 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. %1 of %2 changed from %3 to %4. @@ -809,7 +809,7 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. Cannot find property %1 of object %2. @@ -824,129 +824,139 @@ These settings can be changed at any time from the "Settings" menu.%1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). - + Unknown character "%1". Unknown character "%1". - - + + Illegal escape sequence: %1. Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 Parse error [%1:%2]: %3 - + Expected %1 Expected %1 - + Unexpected %1 Unexpected %1 - + Function definition is not permitted. Function definition is not permitted. - + Expected variable for assignment. Expected variable for assignment. - + Unexpected ".": member access is not permitted Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. Unexpected symbol: %1. - + First argument to map is not a function. First argument to map is not a function. - + Second argument to map is not an array. Second argument to map is not an array. - + First argument to fold is not a function. First argument to fold is not a function. - + Second argument to fold is not an array. Second argument to fold is not an array. - + First argument to filter is not a function. First argument to filter is not a function. - + Second argument to filter is not an array. Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - + Second argument to join is not an array. Second argument to join is not an array. - + EOF End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. + + + Circular dependency detected. Object %1 depends on %2. + + + + + Circular dependency detected. Objects %1 depend on %2. + + expression @@ -1085,114 +1095,114 @@ Please make sure your LaTeX installation is correct and report a bug if so. parameters - + above ↑ Above - + below ↓ Below - - + + left ← Left - - + + right → Right - + above-left ↖ Above left - + above-right ↗ Above right - + below-left ↙ Below left - + below-right ↘ Below right - + center >|< Center - + top ↑ Top - + bottom ↓ Bottom - + top-left ↖ Top left - + top-right ↗ Top right - + bottom-left ↙ Bottom left - + bottom-right ↘ Bottom right - + application Application - + function Function - + high High - + low Low - + Next to target Next to target - + With label With label - + Hidden Hidden diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 992dd8c..b07230b 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -221,32 +221,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -743,12 +743,12 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. @@ -757,7 +757,7 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. @@ -772,129 +772,139 @@ These settings can be changed at any time from the "Settings" menu. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. + + + Circular dependency detected. Object %1 depends on %2. + + + + + Circular dependency detected. Objects %1 depend on %2. + + expression @@ -994,114 +1004,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - + below - - + + left - - + + right - + above-left - + above-right - + below-left - + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index fdb96bd..b3fa2a5 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -254,32 +254,32 @@ ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -804,12 +804,12 @@ These settings can always be changed at any time from the "Settings" m editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 modifiée de "%4" à "%5". - + %1 of %2 changed from %3 to %4. %1 de %2 modifiée de %3 à %4. @@ -818,7 +818,7 @@ These settings can always be changed at any time from the "Settings" m error - + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. @@ -833,129 +833,139 @@ These settings can always be changed at any time from the "Settings" m %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). - + Unknown character "%1". Le caractère "%1" est inconnu. - - + + Illegal escape sequence: %1. Séquence d'échappement illégale : %1. - - + + Parse error [%1:%2]: %3 Erreur de syntaxe [%1:%2] : %3 - + Expected %1 %1 attendu - + Unexpected %1 %1 inattendu - + Function definition is not permitted. La définition de fonctions n'est pas autorisée. - + Expected variable for assignment. Une variable est attendue pour l'affectation. - + Unexpected ".": member access is not permitted "." inattendu : l'accès aux propriétés n'est pas autorisé - + Unexpected "[]": arrays are disabled. "[]" inattendu : les tableaux sont désactivés. - + Unexpected symbol: %1. Symbole inconnu : %1. - + First argument to map is not a function. Le premier argument de map n'est pas une fonction. - + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. + + + Circular dependency detected. Object %1 depends on %2. + + + + + Circular dependency detected. Objects %1 depend on %2. + + expression @@ -1094,114 +1104,114 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c parameters - + above ↑ Au dessus - + below ↓ En dessous - - + + left ← À gauche - - + + right → À droite - + above-left ↖ Au dessus à gauche - + above-right ↗ Au dessus à droite - + below-left ↙ En dessous à gauche - + below-right ↘ En dessous à droite - + center >|< Centré - + top ↑ Au dessus - + bottom ↓ En dessous - + top-left ↖ Au dessus à gauche - + top-right ↗ Au dessus à droite - + bottom-left ↙ En dessous à gauche - + bottom-right ↘ En dessous à droite - + application Application - + function Fonction - + high Haut - + low Bas - + Next to target A côté de la cible - + With label Avec l'étiquette - + Hidden Caché diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 45bcef3..e3b5b8c 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -252,32 +252,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Függvények - + Executable Objects - + Objects Tárgyak @@ -795,12 +795,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. - + %1 of %2 changed from %3 to %4. %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -809,7 +809,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - + Cannot find property %1 of object %2. @@ -824,129 +824,139 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. + + + Circular dependency detected. Object %1 depends on %2. + + + + + Circular dependency detected. Objects %1 depend on %2. + + expression @@ -1078,114 +1088,114 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents parameters - + above ↑ Felett - + below ↓ Alatt - - + + left ← Balra - - + + right → Jobbra - + above-left ↖ Felett, balra - + above-right ↗ Felett, jobbra - + below-left ↙ Alatt, balra - + below-right ↘ Alatt, jobbra - + center >|< Középre - + top ↑ Felső - + bottom ↓ Alsó - + top-left ↖ Bal felső - + top-right ↗ Jobb felső - + bottom-left ↙ Bal alsó - + bottom-right ↘ Jobb alsó - + application Alkalmazás - + function Függvény - + high Magas - + low Alul - + Next to target Cél mellé - + With label Címkével - + Hidden Rejtett diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index d1becca..7dc0b9c 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -252,32 +252,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -795,12 +795,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. editproperty - + %1 of %2 %3 changed from "%4" to "%5". %1 av %2 %3 endret fra «%4» til «%5». - + %1 of %2 changed from %3 to %4. @@ -809,7 +809,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.error - + Cannot find property %1 of object %2. @@ -824,129 +824,139 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. + + + Circular dependency detected. Object %1 depends on %2. + + + + + Circular dependency detected. Objects %1 depend on %2. + + expression @@ -1069,114 +1079,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - + below - - + + left - - + + right - + above-left - + above-right - + below-left - + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 377be41..40023b7 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -221,32 +221,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -743,12 +743,12 @@ These settings can be changed at any time from the "Settings" menu. editproperty - + %1 of %2 %3 changed from "%4" to "%5". - + %1 of %2 changed from %3 to %4. @@ -757,7 +757,7 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. @@ -772,129 +772,139 @@ These settings can be changed at any time from the "Settings" menu. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. + + + Circular dependency detected. Object %1 depends on %2. + + + + + Circular dependency detected. Objects %1 depend on %2. + + expression @@ -994,114 +1004,114 @@ Please make sure your latex installation is correct and report a bug if so. parameters - + above - + below - - + + left - - + + right - + above-left - + above-right - + below-left - + below-right - + center - + top - + bottom - + top-left - + top-right - + bottom-left - + bottom-right - + application - + function - + high - + low - + Next to target - + With label - + Hidden diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 9ca2878..b20be37 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -475,7 +475,16 @@ Item { } if(expr.requiredObjects().includes(control.self)) throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) - // TODO: Check for recursive dependencies. + // Recursive dependencies + let dependentOnSelfObjects = expr.requiredObjects().filter( + (obj) => Objects.currentObjectsByName[obj].getDependenciesList() + .includes(Objects.currentObjectsByName[control.self]) + ) + if(dependentOnSelfObjects.length == 1) + throw new Error(qsTranslate('error', 'Circular dependency detected. Object %1 depends on %2.').arg(dependentOnSelfObjects[0].toString()).arg(control.self)) + else if(dependentOnSelfObjects.length > 1) + throw new Error(qsTranslate('error', 'Circular dependency detected. Objects %1 depend on %2.').arg(dependentOnSelfObjects.map(obj => obj.toString()).join(', ')).arg(control.self)) + console.log(control.self, propertyName, expr.execute()) return expr } catch(e) { // Error in expression diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 6a3d828..b3d7ee5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -274,9 +274,12 @@ function evaluate(tokens, expr, values) { nstack.push(item); } else if (type === IMEMBER) { n1 = nstack.pop(); - //console.log("Getting property", item.value, "of", n1) + //console.log("Getting property", item.value, "of", n1,":",n1[item.value]) if(item.value in n1) - nstack.push(n1[item.value]); + if(n1[item.value].execute && n1[item.value].cached) + nstack.push(n1[item.value].execute()) + else + nstack.push(n1[item.value]); else throw new Error(qsTranslate('error', 'Cannot find property %1 of object %2.').arg(item.value).arg(n1)) } else if (type === IENDSTATEMENT) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 907bf63..5046005 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -187,6 +187,17 @@ class DrawableObject { } } + /** + * Returns the recursive list of objects this one depends on. + * @return {array} + */ + getDependenciesList() { + let dependencies = this.requires.map(obj => obj) + for(let obj of this.requires) + dependencies = dependencies.concat(obj.getDependenciesList()) + return dependencies + } + /** * Callback method when one of the properties of the object is updated. */ @@ -198,24 +209,24 @@ class DrawableObject { this.requires = [] let properties = this.constructor.properties() for(let property in properties) - if(properties[property] == 'Expression' && this[property] != null) { - // Expressions with dependencies - for(let objName of this[property].requiredObjects()) { - if(objName in C.currentObjectsByName && !this.requires.includes(C.currentObjectsByName[objName])) { - this.requires.push(C.currentObjectsByName[objName]) - C.currentObjectsByName[objName].requiredBy.push(this) + if(typeof properties[property] == 'object' && 'type' in properties[property]) + if(properties[property].type == 'Expression' && this[property] != null) { + // Expressions with dependencies + for(let objName of this[property].requiredObjects()) { + if(objName in C.currentObjectsByName && !this.requires.includes(C.currentObjectsByName[objName])) { + this.requires.push(C.currentObjectsByName[objName]) + C.currentObjectsByName[objName].requiredBy.push(this) + } } + if(this[property].cached && this[property].requiredObjects().length > 0) + // Recalculate + this[property].recache() + + } else if(properties[property].type == 'ObjectType' && this[property] != null) { + // Object dependency + this.requires.push(this[property]) + this[property].requiredBy.push(this) } - if(this[property].cached && this[property].requiredObjects().length > 0) - // Recalculate - this[property].recache() - - } else if(typeof properties[property] == 'object' && 'type' in properties[property] && properties[property] == 'ObjectType' && this[property] != null) { - // Object dependency - this.requires.push(this[property]) - this[property].requiredBy.push(this) - } - // Updating objects dependent on this one for(let req of this.requiredBy) req.update() From 677d13278d11162c581a736e03fca21c0543f19c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 18:11:40 +0200 Subject: [PATCH 065/436] Removing debug that made functions crash --- .../qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index b20be37..e4b9840 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -484,7 +484,7 @@ Item { throw new Error(qsTranslate('error', 'Circular dependency detected. Object %1 depends on %2.').arg(dependentOnSelfObjects[0].toString()).arg(control.self)) else if(dependentOnSelfObjects.length > 1) throw new Error(qsTranslate('error', 'Circular dependency detected. Objects %1 depend on %2.').arg(dependentOnSelfObjects.map(obj => obj.toString()).join(', ')).arg(control.self)) - console.log(control.self, propertyName, expr.execute()) + //console.log(control.self, propertyName, expr.execute()) return expr } catch(e) { // Error in expression From 244935d7e20712b1542a9c4bbb3b49c950f809f1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 21:44:08 +0200 Subject: [PATCH 066/436] Adding settings for editor. Also fixing bug with GreetScreen not setting settings in the menu bar, and adding translations. --- LogarithmPlotter/i18n/lp_de.ts | 67 ++++++++++++++----- LogarithmPlotter/i18n/lp_en.ts | 67 ++++++++++++++----- LogarithmPlotter/i18n/lp_es.ts | 67 ++++++++++++++----- LogarithmPlotter/i18n/lp_fr.ts | 67 ++++++++++++++----- LogarithmPlotter/i18n/lp_hu.ts | 67 ++++++++++++++----- LogarithmPlotter/i18n/lp_nb_NO.ts | 67 ++++++++++++++----- LogarithmPlotter/i18n/lp_template.ts | 67 ++++++++++++++----- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 39 +++++++++++ .../LogarithmPlotter/Popup/GreetScreen.qml | 58 +++++++++++++--- .../Setting/ExpressionEditor.qml | 37 +++++----- LogarithmPlotter/util/config.py | 16 ++++- 11 files changed, 481 insertions(+), 138 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 6b28082..e2d67a6 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -103,52 +103,72 @@ LaTeX-Rendering aktivieren - + + Expression editor + + + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -315,32 +335,47 @@ These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Beim Start nach Updates suchen (Online-Verbindung erforderlich) - + Reset redo stack when a new action is added to history Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird - + Enable LaTeX rendering LaTeX-Rendering aktivieren - + + Automatically close parenthesises and brackets in expressions + + + + + Enable syntax highlighting for expressions + + + + + Enable autocompletion interface in expression editor + + + + User manual Benutzerhandbuch - + Changelog Changelog - + Done Schließen diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 9471a63..f324ea6 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -103,52 +103,72 @@ Enable LaTeX rendering - + + Expression editor + + + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -315,32 +335,47 @@ These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history Reset redo stack when a new action is added to history - + Enable LaTeX rendering Enable LaTeX rendering - + + Automatically close parenthesises and brackets in expressions + + + + + Enable syntax highlighting for expressions + + + + + Enable autocompletion interface in expression editor + + + + User manual User manual - + Changelog Changelog - + Done Done diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index b07230b..8fd7ba8 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -103,52 +103,72 @@ Activar el renderizado de LaTeX - + + Expression editor + + + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -283,32 +303,47 @@ These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering Activar el renderizado de LaTeX - + + Automatically close parenthesises and brackets in expressions + + + + + Enable syntax highlighting for expressions + + + + + Enable autocompletion interface in expression editor + + + + User manual - + Changelog - + Done diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index b3fa2a5..7108f13 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -104,52 +104,72 @@ Activer le rendu LaTeX - + + Expression editor + + + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -317,22 +337,37 @@ These settings can be changed at any time from the "Settings" menu. - + Enable LaTeX rendering Activer le rendu LaTeX - + + Automatically close parenthesises and brackets in expressions + + + + + Enable syntax highlighting for expressions + + + + + Enable autocompletion interface in expression editor + + + + User manual Manuel d'utilisation - + Changelog Historique des modifications - + Done Fermer @@ -343,12 +378,12 @@ These settings can always be changed at any time from the "Settings" m These settings can always be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) - + Reset redo stack when a new action is added to history Réinitialiser la pile d'action "Rétablir" lorsqu'une nouvelle action est ajoutée à l'historique diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index e3b5b8c..e70dc44 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -103,52 +103,72 @@ LaTeX-megjelenítés engedélyezése - + + Expression editor + + + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -315,32 +335,47 @@ These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Frissítések keresése indításkor (online kapcsolat szükséges) - + Reset redo stack when a new action is added to history Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - + + Automatically close parenthesises and brackets in expressions + + + + + Enable syntax highlighting for expressions + + + + + Enable autocompletion interface in expression editor + + + + User manual Használati utasítás - + Changelog Változásnapló - + Done Kész diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 7dc0b9c..32ca1b4 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -103,52 +103,72 @@ - + + Expression editor + + + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + &Help &Hjelp - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -315,32 +335,47 @@ These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) - + Reset redo stack when a new action is added to history Tilbakesitll angrehistorikk når en ny handling legges til - + Enable LaTeX rendering - + + Automatically close parenthesises and brackets in expressions + + + + + Enable syntax highlighting for expressions + + + + + Enable autocompletion interface in expression editor + + + + User manual - + Changelog - + Done diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 40023b7..81a2ed7 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -103,52 +103,72 @@ - + + Expression editor + + + + + Automatically close parenthesises and brackets + + + + + Enable syntax highlighting + + + + + Enable autocompletion + + + + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -283,32 +303,47 @@ These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering - + + Automatically close parenthesises and brackets in expressions + + + + + Enable syntax highlighting for expressions + + + + + Enable autocompletion interface in expression editor + + + + User manual - + Changelog - + Done diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 48cf383..748fb4e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -35,6 +35,7 @@ import "js/math/latex.js" as LatexJS \sa LogarithmPlotter */ MenuBar { + property var settings: settingsMenu Menu { title: qsTr("&File") @@ -123,6 +124,7 @@ MenuBar { } Menu { + id: settingsMenu title: qsTr("&Settings") Action { id: checkForUpdatesMenuSetting @@ -154,6 +156,43 @@ MenuBar { } icon.name: 'Expression' } + + Menu { + title: qsTr("Expression editor") + + Action { + id: autocloseFormulaSetting + text: qsTr("Automatically close parenthesises and brackets") + checkable: true + checked: Helper.getSettingBool("expression_editor.autoclose") + onTriggered: { + Helper.setSettingBool("expression_editor.autoclose", checked) + } + icon.name: 'Text' + } + + Action { + id: colorizeFormulaSetting + text: qsTr("Enable syntax highlighting") + checkable: true + checked: Helper.getSettingBool("expression_editor.colorize") + onTriggered: { + Helper.setSettingBool("expression_editor.colorize", checked) + } + icon.name: 'appearance' + } + + Action { + id: autocompleteFormulaSetting + text: qsTr("Enable autocompletion") + checkable: true + checked: Helper.getSettingBool("autocompletion.enabled") + onTriggered: { + Helper.setSettingBool("autocompletion.enabled", checked) + } + icon.name: 'label' + } + } } Menu { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 15c1587..40f2fde 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -95,39 +95,81 @@ Popup { CheckBox { id: checkForUpdatesSetting - anchors.horizontalCenter: parent.horizontalCenter + anchors.left: parent.left + //anchors.horizontalCenter: parent.horizontalCenter anchors.top: helpText.bottom anchors.topMargin: 10 checked: Helper.getSettingBool("check_for_updates") text: qsTr('Check for updates on startup (requires online connectivity)') onClicked: { Helper.setSettingBool("check_for_updates", checked) - //checkForUpdatesMenuSetting.checked = checked + // Set in the menu bar + appMenu.settings.children[0].checked = checked } } CheckBox { id: resetRedoStackSetting - anchors.horizontalCenter: parent.horizontalCenter + anchors.left: parent.left + //anchors.horizontalCenter: parent.horizontalCenter anchors.top: checkForUpdatesSetting.bottom checked: Helper.getSettingBool("reset_redo_stack") text: qsTr('Reset redo stack when a new action is added to history') onClicked: { Helper.setSettingBool("reset_redo_stack", checked) - //resetRedoStackMenuSetting.checked = checked + appMenu.settings.children[1].checked = checked } } CheckBox { id: enableLatexSetting - anchors.horizontalCenter: parent.horizontalCenter + anchors.left: parent.left + //anchors.horizontalCenter: parent.horizontalCenter anchors.top: resetRedoStackSetting.bottom checked: Helper.getSettingBool("enable_latex") text: qsTr('Enable LaTeX rendering') onClicked: { Helper.setSettingBool("enable_latex", checked) - Latex.enabled = checked - drawCanvas.requestPaint() + appMenu.settings.children[2].checked = checked + } + } + + CheckBox { + id: autocloseFormulaSetting + anchors.left: parent.left + //anchors.horizontalCenter: parent.horizontalCenter + anchors.top: enableLatexSetting.bottom + checked: Helper.getSettingBool("expression_editor.autoclose") + text: qsTr('Automatically close parenthesises and brackets in expressions') + onClicked: { + Helper.setSettingBool("expression_editor.autoclose", checked) + appMenu.settings.children[3].children[0].checked = checked + } + } + + CheckBox { + id: colorizeFormulaSetting + anchors.left: parent.left + //anchors.horizontalCenter: parent.horizontalCenter + anchors.top: autocloseFormulaSetting.bottom + checked: Helper.getSettingBool("expression_editor.colorize") + text: qsTr('Enable syntax highlighting for expressions') + onClicked: { + Helper.setSettingBool("expression_editor.colorize", checked) + appMenu.settings.children[3].children[1].checked = checked + } + } + + CheckBox { + id: autocompleteFormulaSetting + anchors.left: parent.left + //anchors.horizontalCenter: parent.horizontalCenter + anchors.top: colorizeFormulaSetting.bottom + checked: Helper.getSettingBool("autocompletion.enabled") + text: qsTr('Enable autocompletion interface in expression editor') + onClicked: { + Helper.setSettingBool("autocompletion.enabled", checked) + appMenu.settings.children[3].children[2].checked = checked } } @@ -159,7 +201,7 @@ Popup { } } - Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()) { + Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()+"a") { greetingPopup.open() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index e4b9840..f0d8f17 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -151,13 +151,15 @@ Item { height: parent.height verticalAlignment: TextInput.AlignVCenter horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter - //font.pixelSize: 14 text: control.defValue - color: "transparent"//sysPalette.windowText + color: syntaxHighlightingEnabled ? "transparent" : sysPalette.windowText focus: true selectByMouse: true - property var tokens: parent.tokens(text) + property bool autocompleteEnabled: Helper.getSettingBool("autocompletion.enabled") + property bool syntaxHighlightingEnabled: Helper.getSettingBool("expression_editor.colorize") + property bool autoClosing: Helper.getSettingBool("expression_editor.autoclose") + property var tokens: autocompleteEnabled || syntaxHighlightingEnabled ? parent.tokens(text) : [] Keys.priority: Keys.BeforeItem // Required for knowing which key the user presses. @@ -176,25 +178,27 @@ Item { //onTextEdited: acPopupContent.itemSelected = 0 onActiveFocusChanged: { - if(activeFocus) + if(activeFocus && autocompleteEnabled) autocompletePopup.open() else autocompletePopup.close() } Keys.onUpPressed: function(event) { - if(acPopupContent.itemSelected == 0) - acPopupContent.itemSelected = acPopupContent.itemCount-1 - else - acPopupContent.itemSelected = acPopupContent.itemSelected-1 + if(autocompleteEnabled) + if(acPopupContent.itemSelected == 0) + acPopupContent.itemSelected = acPopupContent.itemCount-1 + else + acPopupContent.itemSelected = acPopupContent.itemSelected-1 event.accepted = true } Keys.onDownPressed: function(event) { - if(acPopupContent.itemSelected == Math.min(acPopupContent.itemCount-1)) - acPopupContent.itemSelected = 0 - else - acPopupContent.itemSelected = acPopupContent.itemSelected+1 + if(autocompleteEnabled) + if(acPopupContent.itemSelected == Math.min(acPopupContent.itemCount-1)) + acPopupContent.itemSelected = 0 + else + acPopupContent.itemSelected = acPopupContent.itemSelected+1 event.accepted = true } @@ -202,7 +206,7 @@ Item { // Autocomplete popup events //console.log(acPopupContent.currentToken.dot, acPopupContent.previousToken.dot, "@", acPopupContent.currentToken.identifier, acPopupContent.previousToken.identifier, acPopupContent.previousToken2.identifier, objectPropertiesList.objectName, JSON.stringify(objectPropertiesList.baseText), objectPropertiesList.model.length, JSON.stringify(objectPropertiesList.categoryItems)) //console.log("Pressed key:", event.key, Qt.Key_Return, Qt.Key_Enter, event.text, acPopupContent.itemCount) - if((event.key == Qt.Key_Enter || event.key == Qt.Key_Return) && acPopupContent.itemCount > 0) { + if(autocompleteEnabled && (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) && acPopupContent.itemCount > 0) { acPopupContent.autocomplete() event.accepted = true } else @@ -212,7 +216,7 @@ Item { }*/ - if(event.text in openAndCloseMatches) { + if(event.text in openAndCloseMatches && autoClosing) { let start = selectionStart insert(selectionStart, event.text) insert(selectionEnd, openAndCloseMatches[event.text]) @@ -227,8 +231,9 @@ Item { verticalAlignment: TextInput.AlignVCenter horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter textFormat: Text.StyledText - text: colorize(parent.tokens) + text: parent.syntaxHighlightingEnabled ? colorize(parent.tokens) : "" color: sysPalette.windowText + visible: parent.syntaxHighlightingEnabled //font.pixelSize: parent.font.pixelSize //opacity: editor.activeFocus ? 0 : 1 } @@ -537,7 +542,7 @@ Item { parsedText += `${token.value}` break; case Parsing.TokenType.FUNCTION: - parsedText += `${token.value}` + parsedText += `${Utils.escapeHTML(token.value)}` break; case Parsing.TokenType.OPERATOR: parsedText += `${Utils.escapeHTML(token.value)}` diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index 4f7b20c..4f19fd3 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -26,7 +26,15 @@ DEFAULT_SETTINGS = { "check_for_updates": True, "reset_redo_stack": True, "last_install_greet": "0", - "enable_latex": False + "enable_latex": False, + "expression_editor": { + "autoclose": True, + "colorize": True, + "color_scheme": 0, + }, + "autocompletion": { + "enabled": True + } } # Create config directory @@ -51,7 +59,11 @@ def init(): if path.exists(CONFIG_FILE): cfg_data = load(open(CONFIG_FILE, 'r', -1, 'utf8')) for setting_name in cfg_data: - setSetting(setting_name, cfg_data[setting_name]) + if type(cfg_data[setting_name]) == dict: + for setting_name2 in cfg_data[setting_name]: + setSetting(setting_name+"."+setting_name2, cfg_data[setting_name][setting_name2]) + else: + setSetting(setting_name, cfg_data[setting_name]) def save(): """ From a3faeeb7d0dcde79ff00c0c3e38c2bd60bb150d9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 19:45:47 +0000 Subject: [PATCH 067/436] Translated using Weblate (English) Currently translated at 100.0% (253 of 253 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index f324ea6..d12da8e 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -105,22 +105,22 @@ Expression editor - + Expression editor Automatically close parenthesises and brackets - + Automatically close parentheses and brackets Enable syntax highlighting - + Enable syntax highlighting Enable autocompletion - + Enable autocompletion @@ -352,17 +352,17 @@ These settings can be changed at any time from the "Settings" menu. Automatically close parenthesises and brackets in expressions - + Automatically close parentheses and brackets in expressions Enable syntax highlighting for expressions - + Enable syntax highlighting for expressions Enable autocompletion interface in expression editor - + Enable autocompletion interface in expression editor @@ -985,12 +985,12 @@ These settings can be changed at any time from the "Settings" menu. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Objects %1 depend on %2. - + Circular dependency detected. Objects %1 depend on %2. From 9ca8903a3e662d517a87722150ea6a0e7f1d1acf Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 19:51:14 +0000 Subject: [PATCH 068/436] Translated using Weblate (German) Currently translated at 100.0% (253 of 253 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index e2d67a6..10729a1 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -105,22 +105,22 @@ Expression editor - + Ausdruckseditor Automatically close parenthesises and brackets - + Klammern automatisch schließen Enable syntax highlighting - + Syntaxhervorhebung einschalten Enable autocompletion - + Automatische Vervollständigung einschalten @@ -352,17 +352,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Automatically close parenthesises and brackets in expressions - + Automatisches Schließen von Klammern in Ausdrücken Enable syntax highlighting for expressions - + Syntaxhervorhebung für Ausdrücke einschalten Enable autocompletion interface in expression editor - + Schnittstelle zur automatischen Vervollständigung im Ausdruckseditor aktivieren @@ -985,12 +985,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Circular dependency detected. Object %1 depends on %2. - + Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. Circular dependency detected. Objects %1 depend on %2. - + Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. From 4b6d333cee0b468c9330163e33f0ae5f6c4c68b4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 19:48:15 +0000 Subject: [PATCH 069/436] Translated using Weblate (French) Currently translated at 100.0% (253 of 253 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 7108f13..57ec89f 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -106,22 +106,22 @@ Expression editor - + Éditeur de formule Automatically close parenthesises and brackets - + Fermer automatiquement les parenthèses et les crochets Enable syntax highlighting - + Activer la coloration syntaxique Enable autocompletion - + Activer l'autocomplétion @@ -344,17 +344,17 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Automatically close parenthesises and brackets in expressions - + Fermer automatiquement les parenthèses et les crochets dans les formules Enable syntax highlighting for expressions - + Activer la coloration syntaxique des formules Enable autocompletion interface in expression editor - + Activer l'interface d'autocomplétion dans l'éditeur de formules @@ -994,12 +994,12 @@ These settings can always be changed at any time from the "Settings" m Circular dependency detected. Object %1 depends on %2. - + Dépendance circulaire détectée. L'objet %1 dépend de %2. Circular dependency detected. Objects %1 depend on %2. - + Dépendance circulaire détectée. Les objets %1 dépendent de %2. From 86656fe46cb7e1556a4beec61a628e9cbfb7744f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 20 Oct 2022 22:05:45 +0200 Subject: [PATCH 070/436] Bumping version to 0.3.0, removing GreetScreen debug. --- LogarithmPlotter/__init__.py | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- linux/debian/control | 2 +- scripts/package-macosx.sh | 2 +- snapcraft.yaml | 2 +- win/installer.nsi | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index d7eb5e9..4386cbc 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,7 +17,7 @@ """ from shutil import which -__VERSION__ = "0.2.1" +__VERSION__ = "0.3.0" is_release = False diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 40f2fde..542bb25 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -201,7 +201,7 @@ Popup { } } - Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()+"a") { + Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()) { greetingPopup.open() } diff --git a/linux/debian/control b/linux/debian/control index 76f50da..81cbfdf 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -1,6 +1,6 @@ Package: logarithmplotter Source: logarithmplotter -Version: 0.2.1 +Version: 0.3.0 Architecture: all Maintainer: Ad5001 Depends: python3, python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), texlive-latex-base, dvipng diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index 60933a0..019cf2b 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -VERSION=0.2.1 +VERSION=0.3.0 title="LogarithmPlotter v${VERSION} Setup" finalDMGName="LogarithmPlotter-v${VERSION}-setup.dmg" applicationName=LogarithmPlotter diff --git a/snapcraft.yaml b/snapcraft.yaml index aebce42..ebc4625 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,6 +1,6 @@ name: logarithmplotter title: LogarithmPlotter -version: '0.2.1' +version: '0.3.0' summary: 2D logarithmic-scaled plotter software to create asymptotic Bode plots confinement: strict base: core20 diff --git a/win/installer.nsi b/win/installer.nsi index cb5cd41..2d82a83 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -11,7 +11,7 @@ Unicode True !define PROG_ID "LogarithmPlotter.File.1" !define DEV_NAME "Ad5001" !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" -!define VERSION_SHORT "0.2.1" +!define VERSION_SHORT "0.3.0" !define APP_VERSION "${VERSION_SHORT}.0" !define COPYRIGHT "Ad5001 (c) 2022" !define DESCRIPTION "Create graphs with logarithm scales." From d969661b331b9c4431d637b45653d80e9e03c161 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 21 Oct 2022 15:40:01 +0200 Subject: [PATCH 071/436] Fixing autocompletion in case object does not exist. --- .../eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index f0d8f17..34cc4b3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -328,7 +328,7 @@ Item { id: objectPropertiesList category: qsTr("Object Properties") - visbilityCondition: isEnteringProperty + visbilityCondition: doesObjectExist itemStartIndex: 0 itemSelected: parent.itemSelected property bool isEnteringProperty: ( @@ -339,7 +339,8 @@ Item { property string objectName: isEnteringProperty ? (parent.currentToken.dot ? parent.previousToken.value : parent.previousToken2.value) : "" - property var objectProperties: isEnteringProperty ? + property bool doesObjectExist: isEnteringProperty && objectName in Objects.currentObjectsByName + property var objectProperties: doesObjectExist ? Objects.currentObjectsByName[objectName].constructor.properties() : {} categoryItems: Object.keys(objectProperties) From fb1c4c0de75b4672e5bd318cec72357effed0544 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 22 Oct 2022 14:16:15 +0200 Subject: [PATCH 072/436] Using Screen.devicePixelRatio as image depth. Fixes bluriness of images on HDPI screens and disabling it on those who don't need it. --- .../qml/eu/ad5001/LogarithmPlotter/History/History.qml | 2 ++ .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml | 5 +++-- .../qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml | 7 ++++--- .../qml/eu/ad5001/LogarithmPlotter/js/history/common.js | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index e6caf9d..bdbc768 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -18,6 +18,7 @@ import QtQuick 2.12 import QtQml 2.12 +import QtQuick.Window 2.12 import "../js/objects.js" as Objects import "../js/historylib.js" as HistoryLib import "../js/history/common.js" as HistoryCommon @@ -215,5 +216,6 @@ Item { Component.onCompleted: { HistoryLib.history = historyObj HistoryCommon.themeTextColor = sysPalette.windowText + HistoryCommon.imageDepth = Screen.devicePixelRatio } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 11ce7aa..ca02fe9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -19,6 +19,7 @@ import QtQuick 2.12 import QtQuick.Dialogs 1.3 as D import QtQuick.Controls 2.12 +import QtQuick.Window 2.12 import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "../js/objects.js" as Objects import "../js/historylib.js" as HistoryLib @@ -100,8 +101,8 @@ Item { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left visible: LatexJS.enabled - property double depth: 2 - property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*parent.font.pixelSize+4, parent.color).split(",") : ["","0","0"] + property double depth: Screen.devicePixelRatio + property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color).split(",") : ["","0","0"] source: visible ? ltxInfo[0] : "" width: parseInt(ltxInfo[1])/depth height: parseInt(ltxInfo[2])/depth diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index 7df012c..7cf3b31 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -15,7 +15,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import QtQuick 2.7 +import QtQuick 2.12 +import QtQuick.Window 2.12 import QtGraphicalEffects 1.0 /*! @@ -48,8 +49,8 @@ Item { width: parent.width //smooth: true visible: false - sourceSize.width: width*2 - sourceSize.height: width*2 + sourceSize.width: width*Screen.devicePixelRatio + sourceSize.height: width*Screen.devicePixelRatio } ColorOverlay { anchors.fill: img diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js index 92811d9..0cdf6a7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js @@ -98,7 +98,7 @@ class Action { renderLatexAsHtml(latexString) { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") - let latexInfo = Latex.Renderer.render(latexString, imageDepth*fontSize+4, themeTextColor).split(",") + let latexInfo = Latex.Renderer.render(latexString, imageDepth*(fontSize+2), themeTextColor).split(",") return `` } From b0b77834a894a172b7abe46c442ec9b3eac2355a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 22 Oct 2022 14:17:52 +0200 Subject: [PATCH 073/436] Fixing inability to open and load files due to greet screen fixes. --- .../qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 4 ++-- .../eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 748fb4e..a26dd0a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -35,7 +35,7 @@ import "js/math/latex.js" as LatexJS \sa LogarithmPlotter */ MenuBar { - property var settings: settingsMenu + property var settingsMenu: settingsSubMenu Menu { title: qsTr("&File") @@ -124,7 +124,7 @@ MenuBar { } Menu { - id: settingsMenu + id: settingsSubMenu title: qsTr("&Settings") Action { id: checkForUpdatesMenuSetting diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 542bb25..ba25558 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -104,7 +104,7 @@ Popup { onClicked: { Helper.setSettingBool("check_for_updates", checked) // Set in the menu bar - appMenu.settings.children[0].checked = checked + appMenu.settingsMenu.children[0].checked = checked } } @@ -117,7 +117,7 @@ Popup { text: qsTr('Reset redo stack when a new action is added to history') onClicked: { Helper.setSettingBool("reset_redo_stack", checked) - appMenu.settings.children[1].checked = checked + appMenu.settingsMenu.children[1].checked = checked } } @@ -130,7 +130,7 @@ Popup { text: qsTr('Enable LaTeX rendering') onClicked: { Helper.setSettingBool("enable_latex", checked) - appMenu.settings.children[2].checked = checked + appMenu.settingsMenu.children[2].checked = checked } } @@ -143,7 +143,7 @@ Popup { text: qsTr('Automatically close parenthesises and brackets in expressions') onClicked: { Helper.setSettingBool("expression_editor.autoclose", checked) - appMenu.settings.children[3].children[0].checked = checked + appMenu.settingsMenu.children[3].children[0].checked = checked } } @@ -156,7 +156,7 @@ Popup { text: qsTr('Enable syntax highlighting for expressions') onClicked: { Helper.setSettingBool("expression_editor.colorize", checked) - appMenu.settings.children[3].children[1].checked = checked + appMenu.settingsMenu.children[3].children[1].checked = checked } } @@ -169,7 +169,7 @@ Popup { text: qsTr('Enable autocompletion interface in expression editor') onClicked: { Helper.setSettingBool("autocompletion.enabled", checked) - appMenu.settings.children[3].children[2].checked = checked + appMenu.settingsMenu.children[3].children[2].checked = checked } } From 0a064694f5a9c7ddd18c259fc2c6e5581078433f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 22 Oct 2022 18:26:36 +0200 Subject: [PATCH 074/436] Adding new functions for autocomplete, and disabling the ones not implemented in expr-eval. --- .../ad5001/LogarithmPlotter/js/expr-eval.js | 13 +- .../LogarithmPlotter/js/objs/gainbode.js | 2 +- .../LogarithmPlotter/js/parsing/polyfill.js | 136 ++++++++++++++++++ .../LogarithmPlotter/js/parsing/reference.js | 103 ++++++++----- 4 files changed, 209 insertions(+), 45 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index b3d7ee5..92d8cd9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -1627,10 +1627,10 @@ function min(array) { function arrayMap(f, a) { if (typeof f !== 'function') { - throw new Error(qsTranslate('error', 'First argument to map is not a function.')); + throw new EvalError(qsTranslate('error', 'First argument to map is not a function.')); } if (!Array.isArray(a)) { - throw new Error(qsTranslate('error', 'Second argument to map is not an array.')); + throw new EvalError(qsTranslate('error', 'Second argument to map is not an array.')); } return a.map(function (x, i) { return f(x, i); @@ -1639,10 +1639,10 @@ function arrayMap(f, a) { function arrayFold(f, init, a) { if (typeof f !== 'function') { - throw new Error(qsTranslate('error', 'First argument to fold is not a function.')); + throw new EvalError(qsTranslate('error', 'First argument to fold is not a function.')); } if (!Array.isArray(a)) { - throw new Error(qsTranslate('error', 'Second argument to fold is not an array.')); + throw new EvalError(qsTranslate('error', 'Second argument to fold is not an array.')); } return a.reduce(function (acc, x, i) { return f(acc, x, i); @@ -1651,10 +1651,10 @@ function arrayFold(f, init, a) { function arrayFilter(f, a) { if (typeof f !== 'function') { - throw new Error(qsTranslate('error', 'First argument to filter is not a function.')); + throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')); } if (!Array.isArray(a)) { - throw new Error(qsTranslate('error', 'Second argument to filter is not an array.')); + throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.')); } return a.filter(function (x, i) { return f(x, i); @@ -1773,6 +1773,7 @@ class Parser { atan2: Math.atan2, 'if': condition, gamma: gamma, + 'Γ': gamma, roundTo: roundTo, map: arrayMap, fold: arrayFold, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index 0130a9e..84f271b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -112,7 +112,7 @@ class GainBode extends Common.ExecutableObject { draw(canvas, ctx) { var base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)] - var dbfn = new MathLib.Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) + var dbfn = new MathLib.Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`) var inDrawDom = new MathLib.EmptySet() if(this.pass == 'high') { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js new file mode 100644 index 0000000..1638b28 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js @@ -0,0 +1,136 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Contains polyfill math functions used for reference. + +.pragma library + +function factorial(x) { + if (x < 0) // Integrating by less than 0 + if(isFinite(n)) + return Infinity + else + throw new EvalError("Cannot calculate the factorial of -∞.") + + return gamma(x+1) +} + +let GAMMA_G = 4.7421875 +let GAMMA_P = [ + 0.99999999999999709182, + 57.156235665862923517, -59.597960355475491248, + 14.136097974741747174, -0.49191381609762019978, + 0.33994649984811888699e-4, + 0.46523628927048575665e-4, -0.98374475304879564677e-4, + 0.15808870322491248884e-3, -0.21026444172410488319e-3, + 0.21743961811521264320e-3, -0.16431810653676389022e-3, + 0.84418223983852743293e-4, -0.26190838401581408670e-4, + 0.36899182659531622704e-5 +] + +function gamma(n) { + if(n <= 0) // Integrating by less than 0 + if(isFinite(n)) + return Infinity + else + throw new EvalError("Cannot calculate Γ(-∞).") + + if(n >= 171.35) + return Infinity // Would return more than 2^1024 - 1 (aka Number.INT_MAX) + + if(n === Math.round(n) && isFinite(n)) { + // Calculating (n-1)! + let res = n - 1 + + for(let i = n - 2; i > 1; i++) + res *= i + + if(res === 0) + res = 1 // 0! is per definition 1 + + return res + } + + // Section below adapted function adapted from math.js + if(n < 0.5) + return Math.PI / (Math.sin(Math.PI * n) * gamma(1 - n)) + + if(n > 85.0) { // Extended Stirling Approx + let twoN = n * n + let threeN = twoN * n + let fourN = threeN * n + let fiveN = fourN * n + return Math.sqrt(2 * Math.PI / n) * Math.pow((n / Math.E), n) * + (1 + (1 / (12 * n)) + (1 / (288 * twoN)) - (139 / (51840 * threeN)) - + (571 / (2488320 * fourN)) + (163879 / (209018880 * fiveN)) + + (5246819 / (75246796800 * fiveN * n))) + } + + --n + let x = GAMMA_P[0] + for (let i = 1 i < GAMMA_P.length ++i) { + x += GAMMA_P[i] / (n + i) + } + + let t = n + GAMMA_G + 0.5 + return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x +} + +function arrayMap(f, arr) { + if (typeof f != 'function') + throw new EvalError(qsTranslate('error', 'First argument to map is not a function.')) + if (!Array.isArray(arr)) + throw new EvalError(qsTranslate('error', 'Second argument to map is not an array.')) + return arr.map(f) +} + +function arrayFold(f, init, arr) { + if (typeof f != 'function') + throw new EvalError(qsTranslate('error', 'First argument to fold is not a function.')) + if (!Array.isArray(arr)) + throw new EvalError(qsTranslate('error', 'Second argument to fold is not an array.')) + return arr.reduce(f, init) +} + +function arrayFilter(f, arr) { + if (typeof f != 'function') + throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')) + if (!Array.isArray(arr)) + throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.')) + return arr.filter(f) +} + +function arrayFilter(f, arr) { + if (typeof f != 'function') + throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')) + if (!Array.isArray(arr)) + throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.')) + return arr.filter(f) +} + +function arrayJoin(sep, arr) { + if (!Array.isArray(arr)) + throw new Error(qsTranslate('error', 'Second argument to join is not an array.')) + return arr.join(sep) +} + +function indexOf(target, s) { + if (!(Array.isArray(s) || typeof s === 'string')) + throw new Error(qsTranslate('error', 'Second argument to indexOf is not a string or array.')) + return s.indexOf(target) +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js index 81470f2..66d8bf0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js @@ -18,54 +18,81 @@ .pragma library +.import "polyfill.js" as Polyfill + + const CONSTANTS = { "π": Math.PI, "pi": Math.PI, "inf": Infinity, "infinity": Infinity, "∞": Infinity, - "e": Infinity + "e": Math.E }; const CONSTANTS_LIST = Object.keys(CONSTANTS); const FUNCTIONS = { - "abs": Math.abs, - "acos": Math.acos, - "acosh": Math.acosh, - "asin": Math.asin, - "asinh": Math.asinh, - "atan": Math.atan, - "atan2": Math.atan2, - "atanh": Math.atanh, - "cbrt": Math.cbrt, - "ceil": Math.ceil, - "clz32": Math.clz32, - "cos": Math.cos, - "cosh": Math.cosh, - "exp": Math.exp, - "expm1": Math.expm1, - "floor": Math.floor, - "fround": Math.fround, - "hypot": Math.hypot, - "imul": Math.imul, - "log": Math.log, - "log10": Math.log10, - "log1p": Math.log1p, - "log2": Math.log2, - "max": Math.max, - "min": Math.min, - "pow": Math.log2, - "random": Math.random, - "round": Math.round, - "sign": Math.sign, - "sin": Math.sin, - "sinh": Math.sinh, - "sqrt": Math.sqrt, - "tan": Math.tan, - "tanh": Math.tanh, - "trunc": Math.trunc, - "integral": () => 0, // TODO: Implement - "derivative": () => 0, + // The functions commented are the one either not implemented + // in the parser, or not to be used for autocompletion. + // Unary operators + //'+': Number, + //'-': (x) => -x, + //'!' + // Other operations + 'length': (s) => Array.isArray(s) ? s.length : String(s).length, + // Boolean functions + 'not': (x) => !x, + // Math functions + 'abs': Math.abs, + 'acos': Math.acos, + 'acosh': Math.acosh, + 'asin': Math.asin, + 'asinh': Math.asinh, + 'atan': Math.atan, + 'atan2': Math.atan2, + 'atanh': Math.atanh, + 'cbrt': Math.cbrt, + 'ceil': Math.ceil, + //'clz32': Math.clz32, + 'cos': Math.cos, + 'cosh': Math.cosh, + 'exp': Math.exp, + 'expm1': Math.expm1, + 'floor': Math.floor, + //'fround': Math.fround, + 'hypot': Math.hypot, + //'imul': Math.imul, + 'lg': Math.log10, + 'ln': Math.log, + 'log': Math.log, + 'log10': Math.log10, + 'log1p': Math.log1p, + 'log2': Math.log2, + 'max': Math.max, + 'min': Math.min, + 'pow': Math.log2, + 'random': Math.random, + 'round': Math.round, + 'sign': Math.sign, + 'sin': Math.sin, + 'sinh': Math.sinh, + 'sqrt': Math.sqrt, + 'tan': Math.tan, + 'tanh': Math.tanh, + 'trunc': Math.trunc, + // Functions in expr-eval, ported here. + 'fac': Polyfill.factorial, + 'gamma': Polyfill.gamma, + 'Γ': Polyfill.gamma, + 'roundTo': (x, exp) => Number(x).toFixed(exp), + 'map': Polyfill.arrayMap, + 'fold': Polyfill.arrayFold, + 'filter': Polyfill.arrayFilter, + 'indexOf': Polyfill.indexOf, + 'join': Polyfill.arrayJoin, + // Integral & derivative (only here for autocomplete). + 'integral': () => 0, // TODO: Implement + 'derivative': () => 0, } const FUNCTIONS_LIST = Object.keys(FUNCTIONS); // TODO: Complete From 02c7cb8afc3a5cbff70f1bb4e7fd2bb7448918cd Mon Sep 17 00:00:00 2001 From: ovari Date: Sat, 22 Oct 2022 07:11:28 +0000 Subject: [PATCH 075/436] Translated using Weblate (Hungarian) Currently translated at 100.0% (253 of 253 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 123 +++++++++++++++++---------------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index e70dc44..70c0500 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -105,22 +105,22 @@ Expression editor - + Kifejezésszerkesztő Automatically close parenthesises and brackets - + Zárójelek automatikus bezárása Enable syntax highlighting - + Mondattani kiemelés engedélyezése Enable autocompletion - + Automatikus befejezés engedélyezése @@ -192,7 +192,7 @@ + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása @@ -200,42 +200,42 @@ Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése LogarithmPlotter - Invalid object name - + LogarithmPlotter - Érvénytelen objektumnév An object with the name '%1' already exists. - + A(z) „%1” nevű objektum már létezik. Name - Név + Név Label content - Címke tartalom + Címketartalom null - üres + üres name - név + név name + value - név + érték + név + érték @@ -274,32 +274,32 @@ Object Properties - + Objektumtulajdonságok Variables - + Változók Constants - + Állandók Functions - Függvények + Függvények Executable Objects - + Függvényobjektumok Objects - Tárgyak + Objektumok @@ -352,17 +352,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Automatically close parenthesises and brackets in expressions - + Zárójelek automatikus bezárása a kifejezésekben Enable syntax highlighting for expressions - + Mondattani kiemelés engedélyezése a kifejezésekhez Enable autocompletion interface in expression editor - + Automatikus befejezési felület engedélyezése a kifejezésszerkesztőben @@ -520,27 +520,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása Delete %1 %2 - %1 %2 törlése + %1 %2 törlése Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 @@ -846,151 +846,151 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Cannot find property %1 of object %2. - + A(z) %2 objektum %1 tulajdonsága nem található. Undefined variable %1. - + A(z) %1 változó nincs meghatározva. %1 cannot be executed. - + A(z) %1 nem függvény. Invalid expression. - + Érvénytelen kifejezés. Invalid expression (parity). - + Érvénytelen kifejezés (paritás). Unknown character "%1". - + Ismeretlen karakter „%1”. Illegal escape sequence: %1. - + Érvénytelen kilépési sorozat: %1. Parse error [%1:%2]: %3 - + Elemzési hiba [%1:%2]: %3 Expected %1 - + Várható %1 Unexpected %1 - + Váratlan %1 Function definition is not permitted. - + A függvény meghatározása nem engedélyezett. Expected variable for assignment. - + A hozzárendeléshez várt változó. Unexpected ".": member access is not permitted - + Váratlan „.”: a tagok hozzáférése nem engedélyezett Unexpected "[]": arrays are disabled. - + Váratlan „[]”: a tömbök le vannak tiltva. Unexpected symbol: %1. - + Váratlan szimbólum: %1. First argument to map is not a function. - + Az első leképezési argumentum nem függvény. Second argument to map is not an array. - + A második leképezési argumentum nem tömb. First argument to fold is not a function. - + Az első behajtási argumentum nem függvény. Second argument to fold is not an array. - + A második behajtási argumentum nem tömb. First argument to filter is not a function. - + Az első szűrési argumentum nem függvény. Second argument to filter is not an array. - + A második szűrési argumentum nem tömb. Second argument to indexOf is not a string or array. - + Az indexOf második argumentuma nem karakterlánc vagy tömb. Second argument to join is not an array. - + A második csatlakozási argumentum nem tömb. EOF - + Kifejezés vége No object found with names %1. - + A(z) %1 nevű objektum nem található. No object found with name %1. - + A(z) %1 nevű objektum nem található. Object cannot be dependent on itself. - + Az objektum nem függhet önmagától. Circular dependency detected. Object %1 depends on %2. - + Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. Circular dependency detected. Objects %1 depend on %2. - + Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. @@ -998,7 +998,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter - Parsing error - + LogarithmPlotter - Elemzési hiba @@ -1006,7 +1006,10 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. %2 Evaluated expression: %3 - + Hiba a(z) %1 tulajdonság kifejezésének elemzésekor: +%2 + +Kiértékelt kifejezés: %3 @@ -1266,12 +1269,12 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Position of %1 %2 set from "%3" to "%4". - + %1 %2 áthelyezve innen: „%3” ide: „%4”. Position of %1 set from %2 to %3. - + %1 áthelyezve innen: %2 ide: %3. From ee26bc04c561b05d82b0e2bcb01e1c282c1e31f6 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 23 Oct 2022 23:26:34 +0200 Subject: [PATCH 076/436] Fixing syntax error. --- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js index 1638b28..9f750d8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js @@ -83,7 +83,7 @@ function gamma(n) { --n let x = GAMMA_P[0] - for (let i = 1 i < GAMMA_P.length ++i) { + for (let i = 1; i < GAMMA_P.length; ++i) { x += GAMMA_P[i] / (n + i) } From 3a36e417387c992a29669fc2b59dc2bf516b3bac Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 24 Oct 2022 04:51:25 +0200 Subject: [PATCH 077/436] Fixing MacOS building version string. --- mac/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mac/Info.plist b/mac/Info.plist index ff60696..dbbe631 100644 --- a/mac/Info.plist +++ b/mac/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.1 + 0.3.0 NSHighResolutionCapable UTExportedTypeDeclarations From 6307855b879388b3f8dce67245a984beeed1bb65 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 28 Oct 2022 16:36:18 +0200 Subject: [PATCH 078/436] Adding v0.3.0 changelog. --- CHANGELOG.md | 53 +++++++++++++++ .../ad5001/LogarithmPlotter/js/expr-eval.js | 4 +- linux/debian/changelog | 41 ++++++++++++ linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 66 +++++++++++++++++++ linux/flatpak | 2 +- scripts/package-linux.sh | 2 +- 6 files changed, 165 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28fdd0b..1680032 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,58 @@ # Changelog +## v0.3.0 (28 Oct 2022) + +**New** + + * New completely revamped expression editor: + * Automatic closing of parentheses and brackets (can be disabled in settings). + * Syntax highlighting (can be disabled in the settings). + * Autocompletion is now available (for function names, variables and constants, object names and properties) (can be disabled in the settings). + * Object properties can now be used in expressions (e.g. if you have a point named A, you can use A.x to access its x value). + * Similarly executable objects (Functions, bode magnitudes and phases, distributions, and sequences) can be now be used in expressions (e.g. if you have a function named 'f', you can access its value using `f()`). + * LaTeX-rendered formulas are now used in the Objects and History tabs when LaTeX rendering is enabled. + * Errors in formulas are now reported in message boxes. + +**Changes** + + * The Object Editor dialog has been completely reworked internally, resulting in notable performance improvements. + * Vast improvements to the objects system: names are now consistently reported and cannot be shared amongst different objects. + * Disabled access to custom variable and function definition in expressions (can cause issues and vulnerabilities) + * When using the set position cursor on Points and Texts, the position change is now saved a single history action: the position setting. + * Distribution are now prefixed with an 'F_' to prevent confusion with X Cursors. + +**Added translations** + + * Autocompletion categories (English, French, German, Hungarian). + * Expression editor settings (English, French, German, Hungarian). + * Expression syntax errors (English, French, German, Hungarian). + * On top of the above: + * Hungarian: v0.2.0 added text (thanks @ovari!) + * Spanish: Menu bars (thanks @Sergio Varela) + * You can contribute to translation on [Weblate](https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/#repository). + +**Fixed bugs** + + * Fixing Texts not being properly recognized as texts when saving. + * Text's 'Disable LaTeX' property is now properly saved. + * X Cursors LaTeX rendering made the app crash. + * Attempting to insert special character no longer automatically saves the expression you're editing. + * Proper HDPI support for icons and buttons (note: HDPI is not available for the rendered canvas yet). + * Support for non-latin characters in variables (e.g. greek letters, subtext, suptext) + * Silent error when misentering variable names in the expression editor causing internal issues preventing you from changing the expression ever again and causing issues and rendering. + * Fixing some utils function simplifying parentheses when they shouldn't have (note: you may see more parentheses than before in expressions). + * (flatpak and KDE SDK) Fixing the sometimes invisible buttons on the objects tab on startup. + * (macos) Application string version does not match LogarithmPlotter's version. + * (debian) (Normally) Fixing deb building. + +**Internal changes** + + * Object dependencies are now registered on both the dependant object, and the object it's depending on. + * Objects now have a proper per-name registry. + * Object Editor Dialog has been reworked to use loaders instead of loading and hiding every property editor for each property. + * Reworked the file loading system to be able to load dependencies properly. + + ## v0.2.0 (22 Apr 2022) **New** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 92d8cd9..0df2661 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -212,7 +212,9 @@ function evaluate(tokens, expr, values) { } } else if (type === IVAR) { // Check for variable value - if (item.value in expr.functions) { + if (/^__proto__|prototype|constructor$/.test(item.value)) { + throw new Error('WARNING: Prototype access detected and denied. If you downloaded this file from the internet, this file might be a virus.'); + } else if (item.value in expr.functions) { nstack.push(expr.functions[item.value]); } else if (item.value in expr.unaryOps && expr.parser.isOperatorEnabled(item.value)) { nstack.push(expr.unaryOps[item.value]); diff --git a/linux/debian/changelog b/linux/debian/changelog index 919e2aa..f4e95a3 100644 --- a/linux/debian/changelog +++ b/linux/debian/changelog @@ -1,3 +1,44 @@ +logarithmplotter (0.3.0) stable; urgency=medium + + * New: Completely revamped expression editor: + * Automatic closing of parentheses and brackets (can be disabled in settings). + * Syntax highlighting (can be disabled in the settings). + * Autocompletion is now available (for function names, variables and constants, object names and properties) (can be disabled in the settings). + * New: Object properties can now be used in expressions (e.g. if you have a point named A, you can use A.x to access its x value). + * Similarly executable objects (Functions, bode magnitudes and phases, distributions, and sequences) can be now be used in expressions (e.g. if you have a function named 'f', you can access its value using `f()`). + * New LaTeX-rendered formulas are now used in the Objects and History tabs when LaTeX rendering is enabled. + * New: Errors in formulas are now reported in message boxes. + + * Changed: The Object Editor dialog has been completely reworked internally, resulting in notable performance improvements. + * Changed: Vast improvements to the objects system: names are now consistently reported and cannot be shared amongst different objects. + * Changed: Disabled access to custom variable and function definition in expressions (can cause issues and vulnerabilities) + * Changed: When using the set position cursor on Points and Texts, the position change is now saved a single history action: the position setting. + * Changed: Distribution are now prefixed with an 'F_' to prevent confusion with X Cursors. + + * Translated: Autocompletion categories (English, French, German, Hungarian). + * Translated: Expression editor settings (English, French, German, Hungarian). + * Translated: Expression syntax errors (English, French, German, Hungarian). + * On top of the above: + * Translated: (Hungarian) v0.2.0 added text (thanks @ovari!) + * Translated: (Spanish) Menu bars (thanks @Sergio Varela) + * Fixing Texts not being properly recognized as texts when saving. + + * Fixed bug: Text's 'Disable LaTeX' property is now properly saved. + * Fixed bug: X Cursors LaTeX rendering made the app crash. + * Fixed bug: Attempting to insert special character no longer automatically saves the expression you're editing. + * Fixed bug: Proper HDPI support for icons and buttons (note: HDPI is not available for the rendered canvas yet). + * Fixed bug: Support for non-latin characters in variables (e.g. greek letters, subtext, suptext) + * Fixed bug: Silent error when misentering variable names in the expression editor causing internal issues preventing you from changing the expression ever again and causing issues and rendering. + * Fixed bug: Some utils function simplifying parentheses when they shouldn't have (note: you may see more parentheses than before in expressions). + * Fixed bug: (Normally) Fixing deb building. + + * Internal changes: Object dependencies are now registered on both the dependant object, and the object it's depending on. + * Internal changes: Objects now have a proper per-name registry. + * Internal changes: Object Editor Dialog has been reworked to use loaders instead of loading and hiding every property editor for each property. + * Internal changes: Reworked the file loading system to be able to load dependencies properly. + + -- Ad5001 Fri, 28 Oct 2022 17:00:00 +0100 + logarithmplotter (0.2.0) stable; urgency=medium * New: (EXPERIMENTAL) LogarithmPlotter now has an optional LaTeX integration. diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 3def02f..240db77 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -115,6 +115,72 @@ + + +

    Changes for v0.3.0:

    +

    New

    +
      +
    • New completely revamped expression editor:
    • +
    • Automatic closing of parentheses and brackets (can be disabled in settings).
    • +
    • Syntax highlighting (can be disabled in the settings).
    • +
    • Autocompletion is now available (for function names, variables and constants, object names and properties) (can be disabled in the settings).
    • +
    • Object properties can now be used in expressions (e.g. if you have a point named A, you can use A.x to access its x value).
    • +
    • Similarly executable objects (Functions, bode magnitudes and phases, distributions, and sequences) can be now be used in expressions (e.g. if you have a function named 'f', you can access its value using `f()`).
    • +
    • LaTeX-rendered formulas are now used in the Objects and History tabs when LaTeX rendering is enabled.
    • +
    • Errors in formulas are now reported in message boxes.
    • +
    +

    Changes

    +
      +
    • The Object Editor dialog has been completely reworked internally, resulting in notable performance improvements.
    • +
    • Vast improvements to the objects system: names are now consistently reported and cannot be shared amongst different objects.
    • +
    • Disabled access to custom variable and function definition in expressions (can cause issues and vulnerabilities)
    • +
    • When using the set position cursor on Points and Texts, the position change is now saved a single history action: the position setting.
    • +
    • Distribution are now prefixed with an 'F_' to prevent confusion with X Cursors.
    • +
    +

    Added translations

    +
      +
    • Autocompletion categories (English, French, German, Hungarian).
    • +
    • Expression editor settings (English, French, German, Hungarian).
    • +
    • Expression syntax errors (English, French, German, Hungarian).
    • +
    • On top of the above:
    • +
    • Hungarian: v0.2.0 added text (thanks @ovari!)
    • +
    • Spanish: Menu bars (thanks @Sergio Varela)
    • +
    • You can contribute to translation on Weblate.
    • +
    +

    Fixed bugs

    +
      +
    • Fixing Texts not being properly recognized as texts when saving.
    • +
    • Text's 'Disable LaTeX' property is now properly saved.
    • +
    • X Cursors LaTeX rendering made the app crash.
    • +
    • Attempting to insert special character no longer automatically saves the expression you're editing.
    • +
    • Proper HDPI support for icons and buttons (note: HDPI is not available for the rendered canvas yet).
    • +
    • Support for non-latin characters in variables (e.g. greek letters, subtext, suptext)
    • +
    • Silent error when misentering variable names in the expression editor causing internal issues preventing you from changing the expression ever again and causing issues and rendering.
    • +
    • Fixing some utils function simplifying parentheses when they shouldn't have (note: you may see more parentheses than before in expressions).
    • +
    • (flatpak and KDE SDK) Fixing the sometimes invisible buttons on the objects tab on startup.
    • +
    • (macos) Application string version does not match LogarithmPlotter's version.
    • +
    • (debian) (Normally) Fixing deb building.
    • +
    +

    Internal changes

    +
      +
    • Object dependencies are now registered on both the dependant object, and the object it's depending on.
    • +
    • Objects now have a proper per-name registry.
    • +
    • Object Editor Dialog has been reworked to use loaders instead of loading and hiding every property editor for each property.
    • +
    • Reworked the file loading system to be able to load dependencies properly.
    • +
    +
    + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-v0.3.0-setup.exe + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/LogarithmPlotter-v0.3.0-setup.dmg + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-0.3.0.tar.gz + + +

    Changes for v0.2.0:

    diff --git a/linux/flatpak b/linux/flatpak index f215689..ead98a6 160000 --- a/linux/flatpak +++ b/linux/flatpak @@ -1 +1 @@ -Subproject commit f215689b354e07b0fc2e6ad6d0213fe873d497dc +Subproject commit ead98a6c7b4807c044b1737120b6787eb3dd183d diff --git a/scripts/package-linux.sh b/scripts/package-linux.sh index 9f8db9e..183550e 100755 --- a/scripts/package-linux.sh +++ b/scripts/package-linux.sh @@ -8,7 +8,7 @@ cd ../../ # Deb sudo python3 setup.py --remove-git-version --command-packages=stdeb.command sdist_dsc \ - --package logarithmplotter --copyright-file linux/debian/copyright --suite impish --depends3 "$(cat linux/debian/depends)" --section science \ + --package logarithmplotter --copyright-file linux/debian/copyright --suite jammy --depends3 "$(cat linux/debian/depends)" --section science \ bdist_deb # Flatpak building From 225ae67834498183a12e5e1067a00d93d69b34c6 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 28 Oct 2022 16:41:20 +0200 Subject: [PATCH 079/436] Releasing v0.3.0! --- LogarithmPlotter/__init__.py | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 4386cbc..26ef788 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -18,7 +18,7 @@ from shutil import which __VERSION__ = "0.3.0" -is_release = False +is_release = True # Check if development version, if so get the date of the latest git patch diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index ba25558..0eb70ac 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -34,7 +34,7 @@ Popup { x: (parent.width-width)/2 y: Math.max(20, (parent.height-height)/2) width: Math.max(welcome.width+70, checkForUpdatesSetting.width, resetRedoStackSetting.width)+20 - height: Math.min(parent.height-40, 500) + height: Math.min(parent.height-40, 700) modal: true focus: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside From fe13351e99dec82856b782ae27170599539fb1c1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 28 Oct 2022 17:38:41 +0200 Subject: [PATCH 080/436] Removing flatpak submodule. --- .gitmodules | 3 --- linux/flatpak | 1 - scripts/package-linux.sh | 4 +++- 3 files changed, 3 insertions(+), 5 deletions(-) delete mode 160000 linux/flatpak diff --git a/.gitmodules b/.gitmodules index 8c591d4..df81e42 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "LogarithmPlotter/qml/eu/ad5001/MixedMenu"] path = LogarithmPlotter/qml/eu/ad5001/MixedMenu url = https://git.ad5001.eu/Ad5001/MixedMenu -[submodule "linux/flatpak"] - path = linux/flatpak - url = https://github.com/Ad5001/eu.ad5001.LogarithmPlotter diff --git a/linux/flatpak b/linux/flatpak deleted file mode 160000 index ead98a6..0000000 --- a/linux/flatpak +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ead98a6c7b4807c044b1737120b6787eb3dd183d diff --git a/scripts/package-linux.sh b/scripts/package-linux.sh index 183550e..af79276 100755 --- a/scripts/package-linux.sh +++ b/scripts/package-linux.sh @@ -16,7 +16,9 @@ FLATPAK_BUILDER=$(which flatpak-builder) if [ -z $FLATPAK_BUILDER ]; then echo "flatpak-builder not installed. Will not proceed to build flatpak." else - cd linux/flatpak + cd linux + git clone https://github.com/Ad5001/eu.ad5001.LogarithmPlotter + cd eu.ad5001.LogarithmPlotter flatpak-builder AppDir eu.ad5001.LogarithmPlotter.json --user --force-clean --install cd ../../ fi From 839f8e9f367146a195681c30217f7229eac8c319 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 28 Oct 2022 18:15:10 +0200 Subject: [PATCH 081/436] Updating changelog to not overflow the popup. --- CHANGELOG.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1680032..dd3b795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,18 +7,18 @@ * New completely revamped expression editor: * Automatic closing of parentheses and brackets (can be disabled in settings). * Syntax highlighting (can be disabled in the settings). - * Autocompletion is now available (for function names, variables and constants, object names and properties) (can be disabled in the settings). + * Autocompletion is now available (for functions, variables and constants, object names and properties) (can be disabled in the settings). * Object properties can now be used in expressions (e.g. if you have a point named A, you can use A.x to access its x value). - * Similarly executable objects (Functions, bode magnitudes and phases, distributions, and sequences) can be now be used in expressions (e.g. if you have a function named 'f', you can access its value using `f()`). + * Executable objects can be now be used in expressions (e.g. if you have a function named 'f', it's accessible using `f()`). * LaTeX-rendered formulas are now used in the Objects and History tabs when LaTeX rendering is enabled. * Errors in formulas are now reported in message boxes. **Changes** * The Object Editor dialog has been completely reworked internally, resulting in notable performance improvements. - * Vast improvements to the objects system: names are now consistently reported and cannot be shared amongst different objects. + * Vast improvements to the objects system: names can no longer be shared amongst different objects. * Disabled access to custom variable and function definition in expressions (can cause issues and vulnerabilities) - * When using the set position cursor on Points and Texts, the position change is now saved a single history action: the position setting. + * When using the set position cursor, the position change is now saved a single history action. * Distribution are now prefixed with an 'F_' to prevent confusion with X Cursors. **Added translations** @@ -39,8 +39,8 @@ * Attempting to insert special character no longer automatically saves the expression you're editing. * Proper HDPI support for icons and buttons (note: HDPI is not available for the rendered canvas yet). * Support for non-latin characters in variables (e.g. greek letters, subtext, suptext) - * Silent error when misentering variable names in the expression editor causing internal issues preventing you from changing the expression ever again and causing issues and rendering. - * Fixing some utils function simplifying parentheses when they shouldn't have (note: you may see more parentheses than before in expressions). + * Silent error when misentering variable names in the expression editor causing internal issues. + * Fixing some utils function simplifying parentheses when they shouldn't have. * (flatpak and KDE SDK) Fixing the sometimes invisible buttons on the objects tab on startup. * (macos) Application string version does not match LogarithmPlotter's version. * (debian) (Normally) Fixing deb building. @@ -49,7 +49,7 @@ * Object dependencies are now registered on both the dependant object, and the object it's depending on. * Objects now have a proper per-name registry. - * Object Editor Dialog has been reworked to use loaders instead of loading and hiding every property editor for each property. + * Object Editor Dialog has been reworked to use loaders insteads. * Reworked the file loading system to be able to load dependencies properly. From ba98fc3611b5b6b033f0783713bf7b0a93d30124 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 28 Oct 2022 19:26:00 +0200 Subject: [PATCH 082/436] Fixing appstream data. --- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 240db77..9aa1f08 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -125,7 +125,7 @@
  • Syntax highlighting (can be disabled in the settings).
  • Autocompletion is now available (for function names, variables and constants, object names and properties) (can be disabled in the settings).
  • Object properties can now be used in expressions (e.g. if you have a point named A, you can use A.x to access its x value).
  • -
  • Similarly executable objects (Functions, bode magnitudes and phases, distributions, and sequences) can be now be used in expressions (e.g. if you have a function named 'f', you can access its value using `f()`).
  • +
  • Similarly executable objects (Functions, bode magnitudes and phases, distributions, and sequences) can be now be used in expressions (e.g. if you have a function named 'f', you can access its value using `f(value)`).
  • LaTeX-rendered formulas are now used in the Objects and History tabs when LaTeX rendering is enabled.
  • Errors in formulas are now reported in message boxes.
  • From 65c42abd26336c9eb7719bb1d540468e251b61e8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 28 Oct 2022 21:53:19 +0200 Subject: [PATCH 083/436] Updating metadata images for the future. --- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 9aa1f08..24186a8 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -1,6 +1,7 @@ + eu.ad5001.LogarithmPlotter eu.ad5001.LogarithmPlotter.desktop logarithmplotter.desktop @@ -85,21 +86,21 @@ https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/ https://hosted.weblate.org/engage/logarithmplotter/ - https://apps.ad5001.eu/img/full/logarithmplotter.png?v=0.2 - https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.2 - https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.2 - https://apps.ad5001.eu/img/de/gain.png?v=0.2 - https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.2 - https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.2 - https://apps.ad5001.eu/img/fr/gain.png?v=0.2 - https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.2 - https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.2 - https://apps.ad5001.eu/img/hu/gain.png - https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png - https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png - https://apps.ad5001.eu/img/no/gain.png - https://apps.ad5001.eu/img/no/logarithmplotter/phase.png - https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png + https://apps.ad5001.eu/img/full/logarithmplotter.png?v=0.3 + https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.3 + https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.3 + https://apps.ad5001.eu/img/de/gain.png?v=0.3 + https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.3 + https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.3 + https://apps.ad5001.eu/img/fr/gain.png?v=0.3 + https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.3 + https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.3 + https://apps.ad5001.eu/img/hu/gain.png?v=0.3 + https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.3 + https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.3 + https://apps.ad5001.eu/img/no/gain.png?v=0.3 + https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.3 + https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.3 From 98f26d49196254f423e0e4b5185c1ebdf3f04d1e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 28 Oct 2022 22:02:52 +0200 Subject: [PATCH 084/436] Removing unclosed tag. --- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 24186a8..28d5d83 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -1,7 +1,6 @@ - eu.ad5001.LogarithmPlotter eu.ad5001.LogarithmPlotter.desktop logarithmplotter.desktop From 78ffc8c6457156ee6886c3a3dcb9514d6a0c7380 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 21 May 2023 22:32:49 +0200 Subject: [PATCH 085/436] Changing RegExpValidator to RegularExpressionValidator. --- .../eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml | 8 ++++---- .../eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml index c71fddd..fea499e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml @@ -140,8 +140,8 @@ Column { visible: control.dictionaryMode height: parent.height width: visible ? 50 : 0 - validator: RegExpValidator { - regExp: control.keyRegexp + validator: RegularExpressionValidator { + regularExpression: control.keyRegexp } verticalAlignment: TextInput.AlignVCenter horizontalAlignment: TextInput.AlignHCenter @@ -180,8 +180,8 @@ Column { id: valueInput height: parent.height width: parent.width - x - deleteButton.width - 5 - validator: RegExpValidator { - regExp: control.valueRegexp + validator: RegularExpressionValidator { + regularExpression: control.valueRegexp } verticalAlignment: TextInput.AlignVCenter horizontalAlignment: TextInput.AlignHCenter diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 1d1073f..dec024c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -113,8 +113,8 @@ Item { verticalAlignment: TextInput.AlignVCenter horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter color: sysPalette.windowText - validator: RegExpValidator { - regExp: control.isInt ? /-?[0-9]+/ : control.isDouble ? /-?[0-9]+(\.[0-9]+)?/ : /.+/ + validator: RegularExpressionValidator { + regularExpression: control.isInt ? /-?[0-9]+/ : control.isDouble ? /-?[0-9]+(\.[0-9]+)?/ : /.+/ } focus: true text: control.defValue From aecc02c606e145fe09f87271a18ba7637c416df2 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 00:15:09 +0200 Subject: [PATCH 086/436] Updating to Qt6 --- LogarithmPlotter/logarithmplotter.py | 10 +- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 23 ++- .../LogarithmPlotter/History/History.qml | 6 +- .../History/HistoryBrowser.qml | 4 +- .../LogarithmPlotter/History/HistoryItem.qml | 6 +- .../LogarithmPlotter/LogGraphCanvas.qml | 12 +- .../LogarithmPlotter/LogarithmPlotter.qml | 10 +- .../ObjectLists/Editor/CustomPropertyList.qml | 4 +- .../ObjectLists/Editor/Dialog.qml | 172 +++++++++-------- .../ObjectLists/ObjectCreationGrid.qml | 6 +- .../ObjectLists/ObjectLists.qml | 6 +- .../ObjectLists/ObjectRow.qml | 14 +- .../LogarithmPlotter/PickLocationOverlay.qml | 6 +- .../ad5001/LogarithmPlotter/Popup/About.qml | 179 ++++++++++-------- .../ad5001/LogarithmPlotter/Popup/Alert.qml | 2 +- .../LogarithmPlotter/Popup/BaseDialog.qml | 54 ++++++ .../LogarithmPlotter/Popup/Changelog.qml | 4 +- .../LogarithmPlotter/Popup/FileDialog.qml | 8 +- .../LogarithmPlotter/Popup/GreetScreen.qml | 4 +- .../Popup/InsertCharacter.qml | 4 +- .../LogarithmPlotter/Popup/ThanksTo.qml | 24 ++- .../eu/ad5001/LogarithmPlotter/Popup/qmldir | 1 + .../Setting/AutocompletionCategory.qml | 4 +- .../Setting/ComboBoxSetting.qml | 4 +- .../Setting/ExpressionEditor.qml | 10 +- .../ad5001/LogarithmPlotter/Setting/Icon.qml | 6 +- .../LogarithmPlotter/Setting/ListSetting.qml | 6 +- .../LogarithmPlotter/Setting/TextSetting.qml | 4 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 4 +- LogarithmPlotter/util/config.py | 2 +- LogarithmPlotter/util/helper.py | 14 +- LogarithmPlotter/util/latex.py | 6 +- LogarithmPlotter/util/native.py | 2 +- LogarithmPlotter/util/update.py | 2 +- setup.py | 2 +- 35 files changed, 362 insertions(+), 263 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 3a8051c..c5e05e5 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -18,10 +18,10 @@ from time import time -from PySide2.QtWidgets import QApplication -from PySide2.QtQml import QQmlApplicationEngine -from PySide2.QtCore import Qt, QTranslator, QLocale -from PySide2.QtGui import QIcon +from PySide6.QtWidgets import QApplication +from PySide6.QtQml import QQmlApplicationEngine +from PySide6.QtCore import Qt, QTranslator, QLocale +from PySide6.QtGui import QIcon from tempfile import TemporaryDirectory from os import getcwd, chdir, environ, path, remove, close @@ -52,7 +52,7 @@ config.init() def get_linux_theme(): des = { - "KDE": "org.kde.desktop", + "KDE": "default", "gnome": "default", "lxqt": "fusion", "mate": "fusion", diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index a26dd0a..2366fe0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Dialogs 1.3 +import QtQuick +import Qt.labs.platform as Native //import QtQuick.Controls 2.15 import eu.ad5001.MixedMenu 1.1 import "js/objects.js" as Objects @@ -133,6 +133,7 @@ MenuBar { checked: Helper.getSettingBool("check_for_updates") onTriggered: Helper.setSettingBool("check_for_updates", checked) icon.name: 'update' + icon.color: sysPalette.buttonText } Action { @@ -142,6 +143,7 @@ MenuBar { checked: Helper.getSettingBool("reset_redo_stack") onTriggered: Helper.setSettingBool("reset_redo_stack", checked) icon.name: 'timeline' + icon.color: sysPalette.buttonText } Action { @@ -155,6 +157,7 @@ MenuBar { drawCanvas.requestPaint() } icon.name: 'Expression' + icon.color: sysPalette.buttonText } Menu { @@ -169,6 +172,7 @@ MenuBar { Helper.setSettingBool("expression_editor.autoclose", checked) } icon.name: 'Text' + icon.color: sysPalette.buttonText } Action { @@ -180,6 +184,7 @@ MenuBar { Helper.setSettingBool("expression_editor.colorize", checked) } icon.name: 'appearance' + icon.color: sysPalette.buttonText } Action { @@ -191,6 +196,7 @@ MenuBar { Helper.setSettingBool("autocompletion.enabled", checked) } icon.name: 'label' + icon.color: sysPalette.buttonText } } } @@ -236,16 +242,17 @@ MenuBar { } } - MessageDialog { + Native.MessageDialog { id: saveUnsavedChangesDialog title: qsTr("Save unsaved changes?") - icon: StandardIcon.Question text: qsTr("This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue?") - standardButtons: StandardButton.Yes | StandardButton.No - onYes: Qt.quit() + buttons: Native.MessageDialog.Save | Native.MessageDialog.Discard | Native.MessageDialog.Cancel + + onSaveClicked: settings.save() + onDiscardClicked: Qt.quit() } - function showSaveUnsavedChangesDialog() { - saveUnsavedChangesDialog.visible = true + function openSaveUnsavedChangesDialog() { + saveUnsavedChangesDialog.open() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index bdbc768..d3cc112 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQml 2.12 -import QtQuick.Window 2.12 +import QtQuick +import QtQml +import QtQuick.Window import "../js/objects.js" as Objects import "../js/historylib.js" as HistoryLib import "../js/history/common.js" as HistoryCommon diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index c1f73a4..554f135 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick.Controls 2.12 -import QtQuick 2.12 +import QtQuick.Controls +import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "../js/utils.js" as Utils diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index 44397af..d679907 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import QtQuick.Controls 2.12 -import QtQuick 2.12 -import QtGraphicalEffects 1.15 +import QtQuick.Controls +import QtQuick +import Qt5Compat.GraphicalEffects import "../js/utils.js" as Utils import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index e35950a..52055b9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import QtQuick 2.12 +import QtQuick import "js/objects.js" as Objects import "js/utils.js" as Utils import "js/mathlib.js" as MathLib @@ -278,7 +278,7 @@ Canvas { for(var xpow = -maxgradx; xpow <= maxgradx; xpow+=1) { var textSize = ctx.measureText("10"+Utils.textsup(xpow)).width if(xpow != 0) - drawVisibleText(ctx, "10"+Utils.textsup(xpow), x2px(Math.pow(10,xpow))-textSize/2, axisxpx+16+(6*(y==0))) + drawVisibleText(ctx, "10"+Utils.textsup(xpow), x2px(Math.pow(10,xpow))-textSize/2, axisxpx+16+(6*(xpow==1))) } } else { for(var x = 1; x < drawMaxX; x += 1) { @@ -308,7 +308,7 @@ Canvas { Draws an horizontal line at \c x plot coordinate using 2D \c ctx. */ function drawXLine(ctx, x) { - if(visible(x, ymax)) { + if(isVisible(x, ymax)) { drawLine(ctx, x2px(x), 0, x2px(x), canvasSize.height) } } @@ -318,7 +318,7 @@ Canvas { Draws an vertical line at \c y plot coordinate using 2D \c ctx. */ function drawYLine(ctx, y) { - if(visible(xmin, y)) { + if(isVisible(xmin, y)) { drawLine(ctx, 0, y2px(y), canvasSize.width, y2px(y)) } } @@ -407,10 +407,10 @@ Canvas { } /*! - \qmlmethod bool LogGraphCanvas::visible(double x, double y) + \qmlmethod bool LogGraphCanvas::isVisible(double x, double y) Checks whether a plot point (\c x, \c y) is visible or not on the canvas. */ - function visible(x, y) { + function isVisible(x, y) { return (x2px(x) >= 0 && x2px(x) <= canvasSize.width) && (y2px(y) >= 0 && y2px(y) <= canvasSize.height) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 0c71421..5d6feea 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -16,11 +16,11 @@ * along with this program. If not, see . */ -import QtQml 2.12 -import QtQuick.Controls 2.12 +import QtQml +import QtQuick.Controls import eu.ad5001.MixedMenu 1.1 import QtQuick.Layouts 1.12 -import QtQuick 2.12 +import QtQuick // Auto loading all objects. import "js/objs/autoload.js" as ALObjects @@ -323,10 +323,10 @@ ApplicationWindow { onTriggered: Qt.quit() // Quit after paint on test build } - onClosing: { + onClosing: function(close) { if(!history.saved) { close.accepted = false - appMenu.showSaveUnsavedChangesDialog() + appMenu.openSaveUnsavedChangesDialog() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 18da95f..cb49fe2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "../../js/objects.js" as Objects import "../../js/historylib.js" as HistoryLib diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 3297139..d83bc10 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -16,10 +16,12 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Dialogs 1.3 as D +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs as D +import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup import "../../js/objects.js" as Objects import "../../js/objs/common.js" as ObjectsCommons import "../../js/historylib.js" as HistoryLib @@ -36,7 +38,7 @@ import "../../js/mathlib.js" as MathLib \sa Loader, ObjectLists */ -D.Dialog { +Popup.BaseDialog { id: objEditor /*! \qmlproperty string EditorDialog::objType @@ -56,99 +58,111 @@ D.Dialog { title: "LogarithmPlotter" width: 350 - height: 400 + minimumHeight: 400 // Disable closing on return/enter, causing issues with autocomplete. - onActionChosen: if(action.key == Qt.Key_Enter || action.key == Qt.Key_Return) action.accepted = false - - Label { - id: dlgTitle - anchors.left: parent.left - anchors.top: parent.top - verticalAlignment: TextInput.AlignVCenter - text: qsTr("Edit properties of %1 %2").arg(Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) - font.pixelSize: 20 - color: sysPalette.windowText - } - - Column { - id: dlgProperties - anchors.top: dlgTitle.bottom - width: objEditor.width - 20 - spacing: 10 - - D.MessageDialog { - id: invalidNameDialog - title: qsTr("LogarithmPlotter - Invalid object name") - text: "" - function showDialog(objectName) { - text = qsTr("An object with the name '%1' already exists.").arg(objectName) - open() - } + // onActionChosen: if(action.key == Qt.Key_Enter || action.key == Qt.Key_Return) action.accepted = false + Item { + anchors { + top: parent.top; + left: parent.left; + bottom: parent.bottom; + right: parent.right; + topMargin: margin; + leftMargin: margin; + bottomMargin: margin; + rightMargin: margin; } - - Setting.TextSetting { - id: nameProperty - height: 30 - label: qsTr("Name") - icon: "common/label.svg" - width: dlgProperties.width - value: objEditor.obj.name - onChanged: function(newValue) { - let newName = Utils.parseName(newValue) - if(newName != '' && objEditor.obj.name != newName) { - if(newName in Objects.currentObjectsByName) { - invalidNameDialog.showDialog(newName) - } else { - history.addToHistory(new HistoryLib.NameChanged( - objEditor.obj.name, objEditor.objType, newName - )) - Objects.renameObject(obj.name, newName) - objEditor.obj = Objects.currentObjects[objEditor.objType][objEditor.objIndex] + + Label { + id: dlgTitle + anchors.left: parent.left + anchors.top: parent.top + verticalAlignment: TextInput.AlignVCenter + text: qsTr("Edit properties of %1 %2").arg(Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) + font.pixelSize: 20 + color: sysPalette.windowText + } + + Column { + id: dlgProperties + anchors.top: dlgTitle.bottom + width: objEditor.width - 20 + spacing: 10 + + Native.MessageDialog { + id: invalidNameDialog + title: qsTr("LogarithmPlotter - Invalid object name") + text: "" + function showDialog(objectName) { + text = qsTr("An object with the name '%1' already exists.").arg(objectName) + open() + } + } + + Setting.TextSetting { + id: nameProperty + height: 30 + label: qsTr("Name") + icon: "common/label.svg" + width: dlgProperties.width + value: objEditor.obj.name + onChanged: function(newValue) { + let newName = Utils.parseName(newValue) + if(newName != '' && objEditor.obj.name != newName) { + if(newName in Objects.currentObjectsByName) { + invalidNameDialog.showDialog(newName) + } else { + history.addToHistory(new HistoryLib.NameChanged( + objEditor.obj.name, objEditor.objType, newName + )) + Objects.renameObject(obj.name, newName) + objEditor.obj = Objects.currentObjects[objEditor.objType][objEditor.objIndex] + objectListList.update() + } + } + } + } + + Setting.ComboBoxSetting { + id: labelContentProperty + height: 30 + width: dlgProperties.width + label: qsTr("Label content") + model: [qsTr("null"), qsTr("name"), qsTr("name + value")] + property var idModel: ["null", "name", "name + value"] + icon: "common/label.svg" + currentIndex: idModel.indexOf(objEditor.obj.labelContent) + onActivated: function(newIndex) { + if(idModel[newIndex] != objEditor.obj.labelContent) { + objEditor.obj.labelContent = idModel[newIndex] + objEditor.obj.update() objectListList.update() } } } - } - - Setting.ComboBoxSetting { - id: labelContentProperty - height: 30 - width: dlgProperties.width - label: qsTr("Label content") - model: [qsTr("null"), qsTr("name"), qsTr("name + value")] - property var idModel: ["null", "name", "name + value"] - icon: "common/label.svg" - currentIndex: idModel.indexOf(objEditor.obj.labelContent) - onActivated: function(newIndex) { - if(idModel[newIndex] != objEditor.obj.labelContent) { - objEditor.obj.labelContent = idModel[newIndex] - objEditor.obj.update() + + // Dynamic properties + CustomPropertyList { + id: dlgCustomProperties + obj: objEditor.obj + + onChanged: { + obj.update() objectListList.update() } } } - - // Dynamic properties - CustomPropertyList { - id: dlgCustomProperties - obj: objEditor.obj - - onChanged: { - obj.update() - objectListList.update() - } - } } /*! - \qmlmethod void EditorDialog::show() + \qmlmethod void EditorDialog::open() Shows the editor after the object to be edited is set. */ - function show() { + function open() { dlgCustomProperties.model = [] // Reset let objProps = Objects.types[objEditor.objType].properties() dlgCustomProperties.model = Object.keys(objProps).map(prop => [prop, objProps[prop]]) // Converted to 2-dimentional array. - objEditor.open() + objEditor.show() } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index bba2622..0c7bd98 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Controls import "../js/objects.js" as Objects import "../js/historylib.js" as HistoryLib import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting @@ -95,7 +95,7 @@ Column { objectEditor.obj = Objects.currentObjects[modelData][Objects.currentObjects[modelData].length - 1] objectEditor.objType = modelData objectEditor.objIndex = Objects.currentObjects[modelData].length - 1 - objectEditor.show() + objectEditor.open() } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 99e08a7..6e3a397 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Dialogs 1.3 as D -import QtQuick.Controls 2.12 +import QtQuick +// import QtQuick.Dialogs 1.3 as D +import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.ObjectLists.Editor 1.0 as Editor import "../js/objects.js" as Objects diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index ca02fe9..24e4f25 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -16,10 +16,10 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Dialogs 1.3 as D -import QtQuick.Controls 2.12 -import QtQuick.Window 2.12 +import QtQuick +import QtQuick.Dialogs +import QtQuick.Controls +import QtQuick.Window import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "../js/objects.js" as Objects import "../js/historylib.js" as HistoryLib @@ -115,7 +115,7 @@ Item { objEditor.objType = obj.type objEditor.objIndex = index //objEditor.editingRow = objectRow - objEditor.show() + objEditor.open() } } } @@ -193,9 +193,9 @@ Item { } } - D.ColorDialog { + ColorDialog { id: pickColor - color: obj.color + selectedColor: obj.color title: qsTr("Pick new color for %1 %2").arg(obj.constructor.displayType()).arg(obj.name) onAccepted: { history.addToHistory(new HistoryLib.ColorChanged( diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 5460160..a2898d7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Controls import "js/objects.js" as Objects import "js/mathlib.js" as MathLib import "js/historylib.js" as HistoryLib @@ -90,7 +90,7 @@ Item { hoverEnabled: parent.visible cursorShape: Qt.CrossCursor acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: { + onClicked: function(mouse) { if(mouse.button == Qt.LeftButton) { // Validate let newValueX = !parent.pickX ? null : parseValue(picked.mouseX.toString(), objType, propertyX) let newValueY = !parent.pickY ? null : parseValue(picked.mouseY.toString(), objType, propertyY) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml index 7e1687c..a47a2ca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml @@ -16,9 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Dialogs 1.3 as D -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Controls /*! \qmltype About @@ -27,98 +26,112 @@ import QtQuick.Controls 2.12 \sa LogarithmPlotter */ -D.Dialog { +BaseDialog { id: about title: qsTr("About LogarithmPlotter") width: 400 - height: 600 + minimumHeight: 600 - Image { - id: logo - source: "../icons/logarithmplotter.svg" - sourceSize.width: 64 - sourceSize.height: 64 - width: 64 - height: 64 - anchors.horizontalCenter: parent.horizontalCenter - anchors.rightMargin: width/2 - anchors.top: parent.top - anchors.topMargin: 10 - } - - Label { - id: appName - anchors.top: logo.bottom - anchors.left: parent.left - anchors.topMargin: 10 - horizontalAlignment: Text.AlignHCenter - width: parent.width - wrapMode: Text.WordWrap - font.pixelSize: 25 - text: qsTr("LogarithmPlotter v%1").arg(Helper.getVersion()) - } - - Label { - id: description - anchors.top: appName.bottom - anchors.left: parent.left - anchors.topMargin: 10 - horizontalAlignment: Text.AlignHCenter - width: parent.width - wrapMode: Text.WordWrap - font.pixelSize: 18 - text: qsTr("2D plotter software to make BODE plots, sequences and repartition functions.") - } - - Label { - id: debugInfos - anchors.top: description.bottom - anchors.left: parent.left - anchors.topMargin: 10 - horizontalAlignment: Text.AlignHCenter - width: parent.width - wrapMode: Text.WordWrap - font.pixelSize: 14 - text: Helper.getDebugInfos() - } - - Label { - id: copyrightInfos - anchors.top: debugInfos.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: 10 - width: Math.min(410, parent.width) - wrapMode: Text.WordWrap - textFormat: Text.RichText - font.pixelSize: 13 - text: "Copyright © 2022 Ad5001 <mail@ad5001.eu>
    + Item { + anchors { + top: parent.top; + left: parent.left; + bottom: parent.bottom; + right: parent.right; + topMargin: margin; + leftMargin: margin; + bottomMargin: margin; + rightMargin: margin; + } + + Image { + id: logo + source: "../icons/logarithmplotter.svg" + sourceSize.width: 64 + sourceSize.height: 64 + width: 64 + height: 64 + anchors.horizontalCenter: parent.horizontalCenter + anchors.rightMargin: width/2 + anchors.top: parent.top + anchors.topMargin: 10 + } + + Label { + id: appName + anchors.top: logo.bottom + anchors.left: parent.left + anchors.topMargin: 10 + horizontalAlignment: Text.AlignHCenter + width: parent.width + wrapMode: Text.WordWrap + font.pixelSize: 25 + text: qsTr("LogarithmPlotter v%1").arg(Helper.getVersion()) + } + + Label { + id: description + anchors.top: appName.bottom + anchors.left: parent.left + anchors.topMargin: 10 + horizontalAlignment: Text.AlignHCenter + width: parent.width + wrapMode: Text.WordWrap + font.pixelSize: 18 + text: qsTr("2D plotter software to make BODE plots, sequences and repartition functions.") + } + + Label { + id: debugInfos + anchors.top: description.bottom + anchors.left: parent.left + anchors.topMargin: 10 + horizontalAlignment: Text.AlignHCenter + width: parent.width + wrapMode: Text.WordWrap + font.pixelSize: 14 + text: Helper.getDebugInfos() + } + + Label { + id: copyrightInfos + anchors.top: debugInfos.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 10 + width: Math.min(410, parent.width) + wrapMode: Text.WordWrap + textFormat: Text.RichText + font.pixelSize: 13 + text: "Copyright © 2022 Ad5001 <mail@ad5001.eu>

    This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/." - onLinkActivated: Qt.openUrlExternally(link) - } - - Row { - anchors.top: copyrightInfos.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: 10 - spacing: 5 - - Button { - id: openIssueButton - text: qsTr('Report a bug') - icon.name: 'tools-report-bug' - onClicked: Qt.openUrlExternally('https://git.ad5001.eu/Ad5001/LogarithmPlotter') + onLinkActivated: Qt.openUrlExternally(link) } - Button { - id: officialWebsiteButton - text: qsTr('Official website') - icon.name: 'web-browser' - onClicked: Qt.openUrlExternally('https://apps.ad5001.eu/logarithmplotter/') + Row { + id: buttonsRow + anchors.top: copyrightInfos.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 10 + spacing: 5 + + Button { + id: openIssueButton + text: qsTr('Report a bug') + icon.name: 'tools-report-bug' + onClicked: Qt.openUrlExternally('https://git.ad5001.eu/Ad5001/LogarithmPlotter') + } + + Button { + id: officialWebsiteButton + text: qsTr('Official website') + icon.name: 'web-browser' + onClicked: Qt.openUrlExternally('https://apps.ad5001.eu/logarithmplotter/') + } } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml index 4b54697..e27f243 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import QtQuick 2.12 +import QtQuick /*! \qmltype Alert \inqmlmodule eu.ad5001.LogarithmPlotter.Popup diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml new file mode 100644 index 0000000..d96440e --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml @@ -0,0 +1,54 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2022 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick +import QtQuick.Controls + +/*! + \qmltype BaseDialog + \inqmlmodule eu.ad5001.LogarithmPlotter.Popup + \brief Base dialog window in replacement of Dialog Popup from Qt 5. + + \sa LogarithmPlotter +*/ + +Window { + color: sysPalette.window + visible: false; + flags: Qt.Dialog | Qt.Popup | Qt.MSWindowsFixedSizeDialogHint + modality: Qt.WindowModal + minimumWidth: width + maximumWidth: width + height: minimumHeight + // maximumHeight: contentItem.implicitHeight + 2*margin + property int margin: 10 + + Button { + id: closeButton + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.bottomMargin: margin + anchors.rightMargin: margin + text: qsTr('Close') + onClicked: close() + } + + function open() { + show() + } +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index 0bf9247..4052662 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Controls /*! \qmltype Changelog diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml index dc5c8c8..ad967c0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import QtQuick.Dialogs 1.3 as D +import Qt.labs.platform /*! \qmltype FileDialog @@ -25,7 +25,7 @@ import QtQuick.Dialogs 1.3 as D \sa LogarithmPlotter, Settings */ -D.FileDialog { +FileDialog { id: fileDialog property bool exportMode: false @@ -33,6 +33,6 @@ D.FileDialog { title: exportMode ? qsTr("Export Logarithm Plot file") : qsTr("Import Logarithm Plot file") nameFilters: ["Logarithm Plot File (*.lpf)", "All files (*)"] - folder: shortcuts.documents - selectExisting: !exportMode + defaultSuffix: 'lpf' + fileMode: exportMode ? FileDialog.SaveFile : FileDialog.OpenFile } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 0eb70ac..72ca715 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Controls import "../js/math/latex.js" as Latex /*! diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index bbeb3e0..a4d2f4c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick.Controls 2.12 -import QtQuick 2.12 +import QtQuick.Controls +import QtQuick /*! \qmltype InsertCharacter diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml index fce6d1c..d290b78 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Dialogs 1.3 as D -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Dialogs +import QtQuick.Controls /*! \qmltype ThanksTo @@ -27,14 +27,24 @@ import QtQuick.Controls 2.12 \sa LogarithmPlotter */ -D.Dialog { +BaseDialog { id: about title: qsTr("Thanks and Contributions - LogarithmPlotter") - width: 400 - height: 600 + width: 450 + minimumHeight: 710 Column { - anchors.fill: parent + anchors { + top: parent.top; + left: parent.left; + bottom: parent.bottom; + right: parent.right; + topMargin: margin; + leftMargin: margin; + bottomMargin: margin; + rightMargin: margin; + } + spacing: 10 ListView { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir index fb7800e..9306fae 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir @@ -1,5 +1,6 @@ module eu.ad5001.LogarithmPlotter.Popup +BaseDialog 1.0 BaseDialog.qml About 1.0 About.qml Alert 1.0 Alert.qml FileDialog 1.0 FileDialog.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index 7e9f683..6ef6131 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Controls /*! \qmltype AutocompletionCategory diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml index bd572e3..7814f01 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 +import QtQuick +import QtQuick.Controls /*! \qmltype ComboBoxSetting diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 34cc4b3..b64d51c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import QtQuick.Controls 2.12 -import QtQuick 2.12 -import QtQuick.Dialogs 1.3 as D +import QtQuick.Controls +import QtQuick +import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Popup 1.0 as P import "../js/mathlib.js" as MathLib import "../js/utils.js" as Utils @@ -131,7 +131,7 @@ Item { visible: control.label != "" } - D.MessageDialog { + Native.MessageDialog { id: parsingErrorDialog title: qsTranslate("expression", "LogarithmPlotter - Parsing error") text: "" @@ -339,7 +339,7 @@ Item { property string objectName: isEnteringProperty ? (parent.currentToken.dot ? parent.previousToken.value : parent.previousToken2.value) : "" - property bool doesObjectExist: isEnteringProperty && objectName in Objects.currentObjectsByName + property bool doesObjectExist: isEnteringProperty && (objectName in Objects.currentObjectsByName) property var objectProperties: doesObjectExist ? Objects.currentObjectsByName[objectName].constructor.properties() : {} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index 7cf3b31..4966cb8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -15,9 +15,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Window 2.12 -import QtGraphicalEffects 1.0 +import QtQuick +import QtQuick.Window +import Qt5Compat.GraphicalEffects /*! \qmltype Icon diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml index fea499e..1d34828 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import QtQuick 2.12 -import QtQuick.Controls 2.12 -import QtQml.Models 2.12 +import QtQuick +import QtQuick.Controls +import QtQml.Models /*! \qmltype ListSetting diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index dec024c..7247649 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick.Controls 2.12 -import QtQuick 2.12 +import QtQuick.Controls +import QtQuick import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup /*! diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 6bde410..e4ae046 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import QtQuick.Controls 2.12 -import QtQuick 2.12 +import QtQuick.Controls +import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup import "js/utils.js" as Utils diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index 4f19fd3..b528f87 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -19,7 +19,7 @@ from os import path, environ, makedirs from platform import system from json import load, dumps -from PySide2.QtCore import QLocale, QTranslator +from PySide6.QtCore import QLocale, QTranslator DEFAULT_SETTINGS = { diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index 47e3992..df17924 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -16,11 +16,11 @@ * along with this program. If not, see . """ -from PySide2.QtWidgets import QMessageBox, QApplication -from PySide2.QtCore import QRunnable, QThreadPool, QThread, QObject, Signal, Slot, QCoreApplication -from PySide2.QtQml import QQmlApplicationEngine -from PySide2.QtGui import QImage -from PySide2 import __version__ as PySide2_version +from PySide6.QtWidgets import QMessageBox, QApplication +from PySide6.QtCore import QRunnable, QThreadPool, QThread, QObject, Signal, Slot, QCoreApplication +from PySide6.QtQml import QQmlApplicationEngine +from PySide6.QtGui import QImage +from PySide6 import __version__ as PySide6_version from os import chdir, path from json import loads @@ -142,9 +142,9 @@ class Helper(QObject): @Slot(result=str) def getDebugInfos(self): """ - Returns the version info about Qt, PySide2 & Python + Returns the version info about Qt, PySide6 & Python """ - return QCoreApplication.translate('main',"Built with PySide2 (Qt) v{} and python v{}").format(PySide2_version, sys_version.split("\n")[0]) + return QCoreApplication.translate('main',"Built with PySide6 (Qt) v{} and python v{}").format(PySide6_version, sys_version.split("\n")[0]) @Slot() def fetchChangelog(self): diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index d9b4643..628e646 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -16,9 +16,9 @@ * along with this program. If not, see . """ -from PySide2.QtCore import QObject, Slot, Property, QCoreApplication -from PySide2.QtGui import QImage, QColor -from PySide2.QtWidgets import QApplication, QMessageBox +from PySide6.QtCore import QObject, Slot, Property, QCoreApplication +from PySide6.QtGui import QImage, QColor +from PySide6.QtWidgets import QApplication, QMessageBox from os import path, remove from string import Template diff --git a/LogarithmPlotter/util/native.py b/LogarithmPlotter/util/native.py index 2ac1b1b..eae87e8 100644 --- a/LogarithmPlotter/util/native.py +++ b/LogarithmPlotter/util/native.py @@ -18,7 +18,7 @@ # This file contains stuff for native interactions with each OS. -from PySide2.QtCore import QObject, QEvent +from PySide6.QtCore import QObject, QEvent # On macOS, opening a file through finder can only be fetched through the # QFileOpenEvent and NOT throught command line parameters. diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index 5d8917e..6f2c07f 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -16,7 +16,7 @@ * along with this program. If not, see . """ -from PySide2.QtCore import QRunnable, QThreadPool, QThread, QObject, Signal, QCoreApplication +from PySide6.QtCore import QRunnable, QThreadPool, QThread, QObject, Signal, QCoreApplication from urllib.request import urlopen from urllib.error import HTTPError, URLError from sys import argv diff --git a/setup.py b/setup.py index ea494cc..1831e0d 100644 --- a/setup.py +++ b/setup.py @@ -122,7 +122,7 @@ if sys.platform == 'linux': os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') setuptools.setup( - install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide2"]), + install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6"]), python_requires='>=3.8', name='logarithmplotter', From f40c2428779887276bc2c834ac8fef509903ec78 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 00:19:58 +0200 Subject: [PATCH 087/436] Bumping copyright --- LogarithmPlotter/__init__.py | 2 +- LogarithmPlotter/__main__.py | 2 +- LogarithmPlotter/logarithmplotter.py | 2 +- .../qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/History/History.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml | 2 +- .../ObjectLists/Editor/CustomPropertyList.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml | 2 +- .../LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/About.qml | 4 ++-- .../qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml | 2 +- .../LogarithmPlotter/Setting/AutocompletionCategory.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml | 2 +- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/color.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/create.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/delete.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/name.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/position.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/historylib.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/domain.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/expression.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/latex.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js | 2 +- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js | 2 +- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/function.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/point.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/text.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parameters.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js | 2 +- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js | 2 +- LogarithmPlotter/util/config.py | 2 +- LogarithmPlotter/util/helper.py | 2 +- LogarithmPlotter/util/latex.py | 2 +- LogarithmPlotter/util/native.py | 2 +- LogarithmPlotter/util/update.py | 2 +- README.md | 2 +- run.py | 2 +- scripts/generate_manuals.php | 2 +- setup.py | 2 +- 76 files changed, 77 insertions(+), 77 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 26ef788..f206989 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/__main__.py b/LogarithmPlotter/__main__.py index e679d61..62b2568 100644 --- a/LogarithmPlotter/__main__.py +++ b/LogarithmPlotter/__main__.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index c5e05e5..7e1c2af 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 2366fe0..a73da4b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index d3cc112..831bb15 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index 554f135..16feace 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index d679907..bb4b60b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 52055b9..7ab2153 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 5d6feea..bbc826a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index cb49fe2..8c74403 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index d83bc10..eff350c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 0c7bd98..133971d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 6e3a397..4fa963d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 24e4f25..c5e2918 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index a2898d7..d0fb559 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml index a47a2ca..406c348 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -102,7 +102,7 @@ BaseDialog { wrapMode: Text.WordWrap textFormat: Text.RichText font.pixelSize: 13 - text: "Copyright © 2022 Ad5001 <mail@ad5001.eu>
    + text: "Copyright © 2023 Ad5001 <mail@ad5001.eu>

    This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

    diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml index e27f243..dda9e01 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml index d96440e..05de55c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index 4052662..b7efb83 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml index ad967c0..6061ac8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 72ca715..e37e722 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index a4d2f4c..57f7e7d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml index d290b78..80a0c2d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index 6ef6131..df2f9f3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml index 7814f01..936718f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index b64d51c..56df073 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index 4966cb8..5cc6204 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml index 1d34828..30724b2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 7247649..2c6ea9a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index e4ae046..af990de 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js index 4c52aa7..ff4bc54 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js index 0cdf6a7..96020fa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js index 7545372..f47f686 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js index 407f29c..8f651d0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js index 17cc28f..799d26b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js index 0ec790d..aa0299e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js index 1a2ba46..761d7c4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js index ec1a5c8..20f4c31 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js index 70542af..fb43342 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 156394b..59297d8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js index 48c23cf..25f04d2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index 9993152..9c9ae49 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 9ebdf6d..69b7d8c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index 0c43b30..b3e6f51 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js index 1013f82..3d13340 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js index 5fc5d6a..d57f18d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js index 5044942..045cf48 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 5046005..896b0cf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index 85a798f..80ebe3c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index 84f271b..52452f7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index 528910b..4ffd5a7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js index 760ab68..1f27690 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js index dc20a73..7a98b56 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js index 484b7a4..b5cc866 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js index 70e7440..b9e04ce 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js index 5d3f0da..8f16693 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index 99e9936..11ac049 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js index 4d6eb60..5321296 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js index c8d34ca..03e4c9e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js index 30633b6..eca0f78 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js index b81b6e1..a165b69 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js index 05960fd..4e7f6fe 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js index 6dfe932..5cf9f9b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js index 9f750d8..d723444 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js index 66d8bf0..ddc3bdd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js index 63358c0..e782e6f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index da52902..466fc9f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index b528f87..79c0bb7 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index df17924..3b2338f 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 628e646..91ddb3b 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/native.py b/LogarithmPlotter/util/native.py index eae87e8..40ec810 100644 --- a/LogarithmPlotter/util/native.py +++ b/LogarithmPlotter/util/native.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index 6f2c07f..d159a7a 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/README.md b/README.md index bb99c41..f3dc862 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ There are several ways to contribute to LogarithmPlotter. ## Legal notice LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition functions. - Copyright (C) 2022 Ad5001 + Copyright (C) 2023 Ad5001 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/run.py b/run.py index faddd86..a1d78a1 100644 --- a/run.py +++ b/run.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/scripts/generate_manuals.php b/scripts/generate_manuals.php index ec357dc..615f988 100644 --- a/scripts/generate_manuals.php +++ b/scripts/generate_manuals.php @@ -1,7 +1,7 @@ +# Copyright (C) 2023 Ad5001 # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/setup.py b/setup.py index 1831e0d..cb3d90a 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2022 Ad5001 + * Copyright (C) 2023 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From 424eef6e17c43a1b74ae620f55bfa7f646074baf Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 01:50:22 +0200 Subject: [PATCH 088/436] Fixing opening file in settings, updating CI images to PySide6. --- .../eu/ad5001/LogarithmPlotter/Settings.qml | 2 +- ci/drone.yml | 38 +++++++++---------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index af990de..39c508f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -135,7 +135,7 @@ ScrollView { Popup.FileDialog { id: fdiag onAccepted: { - var filePath = fileUrl.toString().substr(7) + var filePath = fdiag.currentFile.toString().substr(7) settings.saveFilename = filePath if(exportMode) { root.saveDiagram(filePath) diff --git a/ci/drone.yml b/ci/drone.yml index 249cbc3..591934e 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -12,10 +12,8 @@ steps: - git submodule update --init --recursive - name: Linux test - image: ad5001/ubuntu-pyside2-xvfb:hirsute-5.15.2 + image: ad5001/ubuntu-pyside6-xvfb:jammy-6.5.0 commands: - #- apt update - #- apt install -y texlive-latex-base dvipng - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test2.lpf @@ -23,7 +21,7 @@ steps: event: [ push, tag ] - name: Windows test - image: ad5001/ubuntu-pyside2-xvfb-wine:win7-5.15.2 + image: ad5001/ubuntu-pyside6-xvfb-wine:jammy-6.5.0 commands: - # For some reason, launching GUI apps with wine, even with xvfb-run, fails. - xvfb-run python run.py --test-build --no-check-for-updates @@ -33,19 +31,19 @@ steps: event: [ push, tag ] -- name: Linux packaging - image: ad5001/accountfree-build-img:hirsute-5.15.2 - commands: - - bash scripts/package-linux.sh - when: - event: [ push, tag ] - - -- name: Windows building - image: ad5001/accountfree-build-img-wine:win7-5.15.2 - commands: - - bash scripts/build-wine.sh - - bash scripts/package-wine.sh - when: - event: [ push, tag ] - +# - name: Linux packaging +# image: ad5001/accountfree-build-img:hirsute-5.15.2 +# commands: +# - bash scripts/package-linux.sh +# when: +# event: [ push, tag ] +# +# +# - name: Windows building +# image: ad5001/accountfree-build-img-wine:win7-5.15.2 +# commands: +# - bash scripts/build-wine.sh +# - bash scripts/package-wine.sh +# when: +# event: [ push, tag ] +# From 508f316bc5436aaec5faee0a458284dfbc686a17 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 03:41:20 +0200 Subject: [PATCH 089/436] Better pick location settings overlay --- .../LogarithmPlotter/PickLocationOverlay.qml | 113 ++++++++++++++---- .../ad5001/LogarithmPlotter/Setting/Icon.qml | 2 +- 2 files changed, 91 insertions(+), 24 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index d0fb559..5173a24 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -18,6 +18,7 @@ import QtQuick import QtQuick.Controls +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "js/objects.js" as Objects import "js/mathlib.js" as MathLib import "js/historylib.js" as HistoryLib @@ -36,6 +37,7 @@ import "js/historylib.js" as HistoryLib Item { id: pickerRoot visible: false + clip: true /*! \qmlproperty var PickLocationOverlay::canvas @@ -120,31 +122,96 @@ Item { } } - Row { - height: precisionSlider.height - Text { - text: " "+ qsTr("Pointer precision:") + " " - color: 'black' - anchors.verticalCenter: parent.verticalCenter - } + + + Rectangle { + id: pickerSettings + radius: 15 + color: sysPalette.window + width: pickerSettingsColumn.width + 30; + height: pickerSettingsColumn.height + 20 + property bool folded: false; + x: -15 - ((width-55) * folded); + y: 10 + z: 2 - Slider { - id: precisionSlider - from: 0 - value: 2 - to: 10 - stepSize: 1 - ToolTip { - parent: precisionSlider.handle - visible: precisionSlider.pressed - text: precisionSlider.value.toFixed(0) + Row { + id: pickerSettingsColumn + anchors { + left: parent.left + top: parent.top + leftMargin: 20 + topMargin: 10 + } + spacing: 15 + property int cellHeight: 15 + + Column { + spacing: 5 + width: 100 + + Text { + text: qsTr("Pointer precision:") + color: sysPalette.windowText + verticalAlignment: Text.AlignVCenter + height: pickerSettingsColumn.cellHeight + } + + Text { + text: qsTr("Snap to grid") + ":" + color: sysPalette.windowText + verticalAlignment: Text.AlignVCenter + height: pickerSettingsColumn.cellHeight + } + } + + Column { + spacing: 5 + + Slider { + id: precisionSlider + from: 0 + value: 2 + to: 10 + stepSize: 1 + height: pickerSettingsColumn.cellHeight + + ToolTip { + parent: precisionSlider.handle + visible: precisionSlider.pressed + text: precisionSlider.value.toFixed(0) + } + } + + CheckBox { + id: snapToGridCheckbox + height: pickerSettingsColumn.cellHeight + // text: qsTr("Snap to grid") + checked: false + } + } + + Button { + width: 24 + anchors.top: parent.top + anchors.bottom: parent.bottom + flat: true + + onClicked: pickerSettings.folded = !pickerSettings.folded + + ToolTip.visible: hovered + ToolTip.delay: 200 + ToolTip.text: pickerSettings.folded ? qsTr("Open picker settings") : qsTr("Hide picker settings") + + Setting.Icon { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: 18 + height: 18 + color: sysPalette.windowText + source: `../icons/common/settings.svg` + } } - } - - CheckBox { - id: snapToGridCheckbox - text: qsTr("Snap to grid") - checked: false } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index 5cc6204..7fa45e7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -47,11 +47,11 @@ Item { id: img height: parent.height width: parent.width - //smooth: true visible: false sourceSize.width: width*Screen.devicePixelRatio sourceSize.height: width*Screen.devicePixelRatio } + ColorOverlay { anchors.fill: img source: img From 93308f2bfa0b77def17772ebf08089ec6c8f9742 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 03:41:50 +0200 Subject: [PATCH 090/436] Forgot adding setting icon --- .../qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg new file mode 100644 index 0000000..4fb694d --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file From 43d78e17e5ad649a9f3f6904d07fa6b1e423fe17 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 04:21:53 +0200 Subject: [PATCH 091/436] Improving LaTeX rendering DPI. --- LogarithmPlotter/util/latex.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index d9b4643..35d8d46 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -86,7 +86,7 @@ class Latex(QObject): Prepares and renders a latex string into a png file. """ markup_hash = hash(latex_markup) - export_path = path.join(self.tempdir.name, f'{markup_hash}_{font_size}_{color.rgb()}') + export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}') if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) # Generating file @@ -97,7 +97,11 @@ class Latex(QObject): self.create_latex_doc(latex_path, latex_markup) self.convert_latex_to_dvi(latex_path) self.cleanup(latex_path) + # Creating four pictures of different sizes to better handle dpi. self.convert_dvi_to_png(latex_path, export_path, font_size, color) + self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) + self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) + self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) except Exception as e: # One of the processes failed. A message will be sent every time. raise e img = QImage(export_path); From 7ec80e6682a10d8f1ad4ad4f9933efae5f3c576d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 05:17:12 +0200 Subject: [PATCH 092/436] Custom color schemes! --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 20 ++++ .../Setting/ExpressionEditor.qml | 98 ++++++++++++++----- LogarithmPlotter/util/helper.py | 8 ++ 3 files changed, 102 insertions(+), 24 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index a26dd0a..21fc23f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -192,6 +192,26 @@ MenuBar { } icon.name: 'label' } + + Menu { + title: qsTr("Color Scheme") + property var schemes: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] + + Repeater { + model: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] + + MenuItem { + text: modelData + checkable: true + checked: Helper.getSettingInt("expression_editor.color_scheme") == index + onTriggered: { + parent.children[Helper.getSettingInt("expression_editor.color_scheme")].checked = false + checked = true + Helper.setSettingInt("expression_editor.color_scheme", index) + } + } + } + } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 34cc4b3..0e976b8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -95,19 +95,74 @@ Item { } /*! - \qmlproperty string ExpressionEditor::colorScheme - Color scheme of the editor, currently based on Breeze Light. - TODO: Make it configurable. + \qmlproperty string ExpressionEditor::colorSchemes + Color schemes of the editor. */ - readonly property var colorScheme: { - 'NORMAL': "#1F1C1B", - 'VARIABLE': "#0057AE", - 'CONSTANT': "#5E2F00", - 'FUNCTION': "#644A9B", - 'OPERATOR': "#A44EA4", - 'STRING': "#9C0E0E", - 'NUMBER': "#805C00" - } + readonly property var colorSchemes: [ + { // Breeze Light + 'NORMAL': "#1F1C1B", + 'VARIABLE': "#0057AE", + 'CONSTANT': "#006E28", + 'FUNCTION': "#644A9B", + 'OPERATOR': "#CA60CA", + 'STRING': "#BF0303", + 'NUMBER': "#B08000" + }, + { // Breeze Dark + 'NORMAL': "#CFCFC2", + 'VARIABLE': "#2980B9", + 'CONSTANT': "#27AE60", + 'FUNCTION': "#8E44AD", + 'OPERATOR': "#A44EA4", + 'STRING': "#F44F4F", + 'NUMBER': "#F67400" + }, + { // Solarized + 'NORMAL': "#839496", + 'VARIABLE': "#B58900", + 'CONSTANT': "#859900", + 'FUNCTION': "#268BD2", + 'OPERATOR': "#859900", + 'STRING': "#2AA198", + 'NUMBER': "#2AA198" + }, + { // GitHub Light + 'NORMAL': "#24292E", + 'VARIABLE': "#D73A49", + 'CONSTANT': "#6F42C1", + 'FUNCTION': "#6F42C1", + 'OPERATOR': "#24292E", + 'STRING': "#032F62", + 'NUMBER': "#005CC5" + }, + { // GitHub Dark + 'NORMAL': "#E1E4E8", + 'VARIABLE': "#F97583", + 'CONSTANT': "#B392f0", + 'FUNCTION': "#B392f0", + 'OPERATOR': "#E1E4E8", + 'STRING': "#9ECBFF", + 'NUMBER': "#79B8FF" + }, + { // Nord + 'NORMAL': "#D8DEE9", + 'VARIABLE': "#81A1C1", + 'CONSTANT': "#8FBCBB", + 'FUNCTION': "#88C0D0", + 'OPERATOR': "#81A1C1", + 'STRING': "#A3BE8C", + 'NUMBER': "#B48EAD" + }, + { // Monokai + 'NORMAL': "#F8F8F2", + 'VARIABLE': "#66D9EF", + 'CONSTANT': "#F92672", + 'FUNCTION': "#A6E22E", + 'OPERATOR': "#F8F8F2", + 'STRING': "#E6DB74", + 'NUMBER': "#AE81FF" + } + ] Icon { id: iconLabel @@ -141,7 +196,6 @@ Item { } } - TextField { id: editor anchors.top: parent.top @@ -204,16 +258,11 @@ Item { Keys.onPressed: function(event) { // Autocomplete popup events - //console.log(acPopupContent.currentToken.dot, acPopupContent.previousToken.dot, "@", acPopupContent.currentToken.identifier, acPopupContent.previousToken.identifier, acPopupContent.previousToken2.identifier, objectPropertiesList.objectName, JSON.stringify(objectPropertiesList.baseText), objectPropertiesList.model.length, JSON.stringify(objectPropertiesList.categoryItems)) - //console.log("Pressed key:", event.key, Qt.Key_Return, Qt.Key_Enter, event.text, acPopupContent.itemCount) if(autocompleteEnabled && (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) && acPopupContent.itemCount > 0) { acPopupContent.autocomplete() event.accepted = true } else acPopupContent.itemSelected = 0 - /*if(event.key == Qt.Key_Left) { // TODO: Don't reset the position when the key moved is still on the same word - if(!acPopupContent.identifierTokenTypes.includes()) - }*/ if(event.text in openAndCloseMatches && autoClosing) { @@ -534,25 +583,26 @@ Item { */ function colorize(tokenList) { let parsedText = "" + let scheme = colorSchemes[Helper.getSettingInt("expression_editor.color_scheme")] for(let token of tokenList) { switch(token.type) { case Parsing.TokenType.VARIABLE: - parsedText += `${token.value}` + parsedText += `${token.value}` break; case Parsing.TokenType.CONSTANT: - parsedText += `${token.value}` + parsedText += `${token.value}` break; case Parsing.TokenType.FUNCTION: - parsedText += `${Utils.escapeHTML(token.value)}` + parsedText += `${Utils.escapeHTML(token.value)}` break; case Parsing.TokenType.OPERATOR: - parsedText += `${Utils.escapeHTML(token.value)}` + parsedText += `${Utils.escapeHTML(token.value)}` break; case Parsing.TokenType.NUMBER: - parsedText += `${Utils.escapeHTML(token.value)}` + parsedText += `${Utils.escapeHTML(token.value)}` break; case Parsing.TokenType.STRING: - parsedText += `${token.limitator}${Utils.escapeHTML(token.value)}${token.limitator}` + parsedText += `${token.limitator}${Utils.escapeHTML(token.value)}${token.limitator}` break; case Parsing.TokenType.WHITESPACE: case Parsing.TokenType.PUNCT: diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index 47e3992..df3dba3 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -123,6 +123,10 @@ class Helper(QObject): def getSetting(self, namespace): return config.getSetting(namespace) + @Slot(str, result=int) + def getSettingInt(self, namespace): + return config.getSetting(namespace) + @Slot(str, result=bool) def getSettingBool(self, namespace): return config.getSetting(namespace) @@ -135,6 +139,10 @@ class Helper(QObject): def setSettingBool(self, namespace, value): return config.setSetting(namespace, value) + @Slot(str, int) + def setSettingInt(self, namespace, value): + return config.setSetting(namespace, value) + @Slot(str) def setLanguage(self, new_lang): config.setSetting("language", new_lang) From 5ef8cac1c05ad39a1c4f09643a1097ec4e98d34c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 05:56:34 +0200 Subject: [PATCH 093/436] Adding color schemes for expressions --- LogarithmPlotter/__init__.py | 2 +- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 3 +- .../LogarithmPlotter/Popup/GreetScreen.qml | 278 +++++++++--------- 3 files changed, 150 insertions(+), 133 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 26ef788..cf95148 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,7 +17,7 @@ """ from shutil import which -__VERSION__ = "0.3.0" +__VERSION__ = "0.4.0" is_release = True diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 21fc23f..5eae7c1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -194,11 +194,12 @@ MenuBar { } Menu { + id: colorSchemeSetting title: qsTr("Color Scheme") property var schemes: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] Repeater { - model: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] + model: colorSchemeSetting.schemes MenuItem { text: modelData diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 0eb70ac..7a6a921 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -37,143 +37,159 @@ Popup { height: Math.min(parent.height-40, 700) modal: true focus: true + clip: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - Item { - id: welcome - height: logo.height - width: logo.width + 10 + welcomeText.width + ScrollView { + anchors.left: parent.left + anchors.right: parent.right anchors.top: parent.top - anchors.topMargin: (parent.width-width)/2 - anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: bottomButtons.height + 20 + clip: true - Image { - id: logo - source: "../icons/logarithmplotter.svg" - sourceSize.width: 48 - sourceSize.height: 48 - width: 48 - height: 48 - } - - Label { - id: welcomeText - anchors.verticalCenter: parent.verticalCenter - anchors.left: logo.right - anchors.leftMargin: 10 - //width: parent.width - wrapMode: Text.WordWrap - font.pixelSize: 32 - text: qsTr("Welcome to LogarithmPlotter") + Column { + width: greetingPopup.width - 25 + spacing: 10 + clip: true + topPadding: 35 + + Row { + id: welcome + height: logo.height + spacing: 10 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + id: logo + source: "../icons/logarithmplotter.svg" + sourceSize.width: 48 + sourceSize.height: 48 + width: 48 + height: 48 + } + + Label { + id: welcomeText + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + font.pixelSize: 32 + text: qsTr("Welcome to LogarithmPlotter") + } + } + + Label { + id: versionText + anchors.horizontalCenter: parent.horizontalCenter + wrapMode: Text.WordWrap + width: implicitWidth + font.pixelSize: 18 + font.italic: true + text: qsTr("Version %1").arg(Helper.getVersion()) + } + + Label { + id: helpText + anchors.horizontalCenter: parent.horizontalCenter + wrapMode: Text.WordWrap + font.pixelSize: 14 + width: parent.width - 50 + text: qsTr("Take a few seconds to configure LogarithmPlotter.\nThese settings can be changed at any time from the \"Settings\" menu.") + } + + CheckBox { + id: checkForUpdatesSetting + anchors.left: parent.left + checked: Helper.getSettingBool("check_for_updates") + text: qsTr('Check for updates on startup (requires online connectivity)') + onClicked: { + Helper.setSettingBool("check_for_updates", checked) + // Set in the menu bar + appMenu.settingsMenu.children[0].checked = checked + } + } + + CheckBox { + id: resetRedoStackSetting + anchors.left: parent.left + checked: Helper.getSettingBool("reset_redo_stack") + text: qsTr('Reset redo stack when a new action is added to history') + onClicked: { + Helper.setSettingBool("reset_redo_stack", checked) + appMenu.settingsMenu.children[1].checked = checked + } + } + + CheckBox { + id: enableLatexSetting + anchors.left: parent.left + checked: Helper.getSettingBool("enable_latex") + text: qsTr('Enable LaTeX rendering') + onClicked: { + Helper.setSettingBool("enable_latex", checked) + appMenu.settingsMenu.children[2].checked = checked + } + } + + CheckBox { + id: autocloseFormulaSetting + anchors.left: parent.left + checked: Helper.getSettingBool("expression_editor.autoclose") + text: qsTr('Automatically close parenthesises and brackets in expressions') + onClicked: { + Helper.setSettingBool("expression_editor.autoclose", checked) + appMenu.settingsMenu.children[3].children[0].checked = checked + } + } + + CheckBox { + id: colorizeFormulaSetting + anchors.left: parent.left + checked: Helper.getSettingBool("expression_editor.colorize") + text: qsTr('Enable syntax highlighting for expressions') + onClicked: { + Helper.setSettingBool("expression_editor.colorize", checked) + appMenu.settingsMenu.children[3].children[1].checked = checked + } + } + + CheckBox { + id: autocompleteFormulaSetting + anchors.left: parent.left + checked: Helper.getSettingBool("autocompletion.enabled") + text: qsTr('Enable autocompletion interface in expression editor') + onClicked: { + Helper.setSettingBool("autocompletion.enabled", checked) + appMenu.settingsMenu.children[3].children[2].checked = checked + } + } + + Row { + anchors.left: parent.left + anchors.leftMargin: 10 + spacing: 10 + + Label { + id: colorSchemeLabel + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + text: qsTr("Color scheme:") + } + + ComboBox { + model: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] + currentIndex: Helper.getSettingInt("expression_editor.color_scheme") + + onActivated: function(index) { + Helper.setSettingInt("expression_editor.color_scheme", index) + } + } + } } } - - Label { - id: versionText - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: welcome.bottom - anchors.topMargin: 10 - //width: parent.width - wrapMode: Text.WordWrap - width: implicitWidth - font.pixelSize: 18 - font.italic: true - text: qsTr("Version %1").arg(Helper.getVersion()) - } - - Label { - id: helpText - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: versionText.bottom - anchors.topMargin: 40 - //width: parent.width - wrapMode: Text.WordWrap - font.pixelSize: 14 - width: parent.width - 50 - text: qsTr("Take a few seconds to configure LogarithmPlotter.\nThese settings can be changed at any time from the \"Settings\" menu.") - } - - CheckBox { - id: checkForUpdatesSetting - anchors.left: parent.left - //anchors.horizontalCenter: parent.horizontalCenter - anchors.top: helpText.bottom - anchors.topMargin: 10 - checked: Helper.getSettingBool("check_for_updates") - text: qsTr('Check for updates on startup (requires online connectivity)') - onClicked: { - Helper.setSettingBool("check_for_updates", checked) - // Set in the menu bar - appMenu.settingsMenu.children[0].checked = checked - } - } - - CheckBox { - id: resetRedoStackSetting - anchors.left: parent.left - //anchors.horizontalCenter: parent.horizontalCenter - anchors.top: checkForUpdatesSetting.bottom - checked: Helper.getSettingBool("reset_redo_stack") - text: qsTr('Reset redo stack when a new action is added to history') - onClicked: { - Helper.setSettingBool("reset_redo_stack", checked) - appMenu.settingsMenu.children[1].checked = checked - } - } - - CheckBox { - id: enableLatexSetting - anchors.left: parent.left - //anchors.horizontalCenter: parent.horizontalCenter - anchors.top: resetRedoStackSetting.bottom - checked: Helper.getSettingBool("enable_latex") - text: qsTr('Enable LaTeX rendering') - onClicked: { - Helper.setSettingBool("enable_latex", checked) - appMenu.settingsMenu.children[2].checked = checked - } - } - - CheckBox { - id: autocloseFormulaSetting - anchors.left: parent.left - //anchors.horizontalCenter: parent.horizontalCenter - anchors.top: enableLatexSetting.bottom - checked: Helper.getSettingBool("expression_editor.autoclose") - text: qsTr('Automatically close parenthesises and brackets in expressions') - onClicked: { - Helper.setSettingBool("expression_editor.autoclose", checked) - appMenu.settingsMenu.children[3].children[0].checked = checked - } - } - - CheckBox { - id: colorizeFormulaSetting - anchors.left: parent.left - //anchors.horizontalCenter: parent.horizontalCenter - anchors.top: autocloseFormulaSetting.bottom - checked: Helper.getSettingBool("expression_editor.colorize") - text: qsTr('Enable syntax highlighting for expressions') - onClicked: { - Helper.setSettingBool("expression_editor.colorize", checked) - appMenu.settingsMenu.children[3].children[1].checked = checked - } - } - - CheckBox { - id: autocompleteFormulaSetting - anchors.left: parent.left - //anchors.horizontalCenter: parent.horizontalCenter - anchors.top: colorizeFormulaSetting.bottom - checked: Helper.getSettingBool("autocompletion.enabled") - text: qsTr('Enable autocompletion interface in expression editor') - onClicked: { - Helper.setSettingBool("autocompletion.enabled", checked) - appMenu.settingsMenu.children[3].children[2].checked = checked - } - } - + Row { + id: bottomButtons anchors.bottom: parent.bottom anchors.bottomMargin: 10 spacing: 10 @@ -201,7 +217,7 @@ Popup { } } - Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()) { + Component.onCompleted: if(Helper.getSetting("last_install_greet") +1 != Helper.getVersion()) { greetingPopup.open() } From bf067b7e7cb54de283290a3c6d43e66c9337b5aa Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 06:11:15 +0200 Subject: [PATCH 094/436] Fixing object edition dialog height --- .../ObjectLists/Editor/Dialog.qml | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index eff350c..8c5fa9a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -58,7 +58,8 @@ Popup.BaseDialog { title: "LogarithmPlotter" width: 350 - minimumHeight: 400 + minimumHeight: Math.max(450,dlgProperties.height + margin*4 + 30) + maximumHeight: minimumHeight // Disable closing on return/enter, causing issues with autocomplete. // onActionChosen: if(action.key == Qt.Key_Enter || action.key == Qt.Key_Return) action.accepted = false @@ -70,25 +71,23 @@ Popup.BaseDialog { right: parent.right; topMargin: margin; leftMargin: margin; - bottomMargin: margin; + bottomMargin: margin + 30; rightMargin: margin; } - Label { - id: dlgTitle - anchors.left: parent.left - anchors.top: parent.top - verticalAlignment: TextInput.AlignVCenter - text: qsTr("Edit properties of %1 %2").arg(Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) - font.pixelSize: 20 - color: sysPalette.windowText - } - Column { id: dlgProperties anchors.top: dlgTitle.bottom width: objEditor.width - 20 spacing: 10 + + Label { + id: dlgTitle + verticalAlignment: TextInput.AlignVCenter + text: qsTr("Edit properties of %1 %2").arg(Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) + font.pixelSize: 20 + color: sysPalette.windowText + } Native.MessageDialog { id: invalidNameDialog From 0539f988e240d90728093ebb1fb61fac68b54216 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 06:17:08 +0200 Subject: [PATCH 095/436] Adding new strings --- LogarithmPlotter/i18n/lp_de.ts | 286 +++++++++++++++------------ LogarithmPlotter/i18n/lp_en.ts | 286 +++++++++++++++------------ LogarithmPlotter/i18n/lp_es.ts | 286 +++++++++++++++------------ LogarithmPlotter/i18n/lp_fr.ts | 286 +++++++++++++++------------ LogarithmPlotter/i18n/lp_hu.ts | 286 +++++++++++++++------------ LogarithmPlotter/i18n/lp_nb_NO.ts | 286 +++++++++++++++------------ LogarithmPlotter/i18n/lp_template.ts | 286 +++++++++++++++------------ 7 files changed, 1134 insertions(+), 868 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 10729a1..970bc48 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -4,28 +4,28 @@ About - + About LogarithmPlotter Über LogarithmPlotter - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. 2D-Grafiksoftware zur Erstellung von Bode-Diagramms, Folgen und Verteilungsfunktionen. - + Report a bug Bug melden - + Official website Offizielle Website @@ -33,146 +33,159 @@ AppMenuBar - + &File &Datei - + &Load... &Laden… - + &Save &Speichern - + Save &As... Speichern &Unter… - + &Quit &Ausfahrt - + &Edit &Bearbeiten - + &Undo &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + &Create &Erstellen - + &Settings &Einstellungen - + Check for updates on startup Beim Starten auf Updates prüfen - + Reset redo stack automaticly Wiederherstellen-Stapel automatisch zurücksetzen - + Enable LaTeX rendering LaTeX-Rendering aktivieren - + Expression editor Ausdruckseditor - + Automatically close parenthesises and brackets Klammern automatisch schließen - + Enable syntax highlighting Syntaxhervorhebung einschalten - + Enable autocompletion Automatische Vervollständigung einschalten - + + Color Scheme + + + + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? + + BaseDialog + + + Close + + + Changelog @@ -198,42 +211,42 @@ Dialog - + Edit properties of %1 %2 Eigenschaften von %1 %2 bearbeiten - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ungültiger Objektname - + An object with the name '%1' already exists. Ein Objekt mit dem Namen '%1' existiert bereits. - + Name Name - + Label content Etikett - + null leer - + name Name - + name + value Name + Wert @@ -272,32 +285,32 @@ ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktion - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -318,24 +331,24 @@ GreetScreen - + Welcome to LogarithmPlotter Willkommen bei LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Nehmen Sie sich ein paar Sekunden Zeit, um LogarithmPlotter zu konfigurieren. Diese Einstellungen können jederzeit über das Menü "Einstellungen" geändert werden. - + Check for updates on startup (requires online connectivity) Beim Start nach Updates suchen (Online-Verbindung erforderlich) @@ -345,37 +358,42 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird - + Enable LaTeX rendering LaTeX-Rendering aktivieren - + Automatically close parenthesises and brackets in expressions Automatisches Schließen von Klammern in Ausdrücken - + Enable syntax highlighting for expressions Syntaxhervorhebung für Ausdrücke einschalten - + Enable autocompletion interface in expression editor Schnittstelle zur automatischen Vervollständigung im Ausdruckseditor aktivieren - + + Color scheme: + + + + User manual Benutzerhandbuch - + Changelog Changelog - + Done Schließen @@ -518,27 +536,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ObjectRow - + Hide %1 %2 Ausblenden %1 %2 - + Show %1 %2 Anzeigen %1 %2 - + Set %1 %2 position Position von %1 %2 einstellen - + Delete %1 %2 %1 %2 löschen - + Pick new color for %1 %2 Neue Farbe für %1 %2 auswählen @@ -546,15 +564,25 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" PickLocationOverlay - + Pointer precision: Genauigkeit des Zeigers: - + Snap to grid Am Gitter einrasten + + + Open picker settings + + + + + Hide picker settings + + Settings @@ -662,87 +690,87 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Danksagungen und Beiträge - LogarithmPlotter - + Source code Quellcode - + Original library by Raphael Graf Originalbibliothek von Raphael Graf - + Source Quelle - + Ported to Javascript by Matthew Crumley Portiert auf Javascript von Matthew Crumley - - - - - + + + + + Website Website - + Ported to QMLJS by Ad5001 Portiert auf QMLJS von Ad5001 - + Libraries included Einschließlich Bibliotheken - + Email E-Mail - + English Englisch - + French Französisch - + German Deutsch - + Hungarian Ungarisch - - + + Github Github - + Norwegian Norwegisch - + Translations included Einschließlich Übersetzungen - + Improve Verbessern @@ -802,7 +830,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - + %1: @@ -844,151 +872,161 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. - + Undefined variable %1. Die Variable %1 ist nicht definiert. - + %1 cannot be executed. %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). - + Unknown character "%1". Unbekanntes Schriftzeichen "%1". - - + + Illegal escape sequence: %1. Unzulässige Escapesequenz: %1. - - + + Parse error [%1:%2]: %3 Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 - + Function definition is not permitted. Funktionsdefinition ist nicht erlaubt. - + Expected variable for assignment. Erwartete Variable für Zuweisung. - + Unexpected ".": member access is not permitted Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt - + Unexpected "[]": arrays are disabled. Unerwartetes "[]": Arrays sind deaktiviert. - + Unexpected symbol: %1. Unerwartetes Symbol: %1. - + + First argument to map is not a function. Der erste Parameter von map ist keine Formel. - + + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - + + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - + + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - + + + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - + + + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - + + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - + + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. @@ -996,12 +1034,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler - + Error while parsing expression for property %1: %2 @@ -1094,7 +1132,7 @@ Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.o DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1107,7 +1145,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index d12da8e..299eee8 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -4,28 +4,28 @@ About - + About LogarithmPlotter About LogarithmPlotter - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. 2D plotter software to make Bode plots, sequences and distribution functions. - + Report a bug Report a bug - + Official website Official website @@ -33,146 +33,159 @@ AppMenuBar - + &File &File - + &Load... &Open… - + &Save &Save - + Save &As... Save &As… - + &Quit &Quit - + &Edit &Edit - + &Undo &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + &Create &Create - + &Settings &Settings - + Check for updates on startup Check for updates on startup - + Reset redo stack automaticly Reset redo stack automatically - + Enable LaTeX rendering Enable LaTeX rendering - + Expression editor Expression editor - + Automatically close parenthesises and brackets Automatically close parentheses and brackets - + Enable syntax highlighting Enable syntax highlighting - + Enable autocompletion Enable autocompletion - + + Color Scheme + + + + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? + + BaseDialog + + + Close + + + Changelog @@ -198,42 +211,42 @@ Dialog - + Edit properties of %1 %2 Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. An object with the name '%1' already exists. - + Name Name - + Label content Label content - + null null - + name name - + name + value name + value @@ -272,32 +285,32 @@ ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -318,24 +331,24 @@ GreetScreen - + Welcome to LogarithmPlotter Welcome to LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Check for updates on startup (requires online connectivity) @@ -345,37 +358,42 @@ These settings can be changed at any time from the "Settings" menu.Reset redo stack when a new action is added to history - + Enable LaTeX rendering Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions Automatically close parentheses and brackets in expressions - + Enable syntax highlighting for expressions Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor Enable autocompletion interface in expression editor - + + Color scheme: + + + + User manual User manual - + Changelog Changelog - + Done Done @@ -518,27 +536,27 @@ These settings can be changed at any time from the "Settings" menu. ObjectRow - + Hide %1 %2 Hide %1 %2 - + Show %1 %2 Show %1 %2 - + Set %1 %2 position Set %1 %2 position - + Delete %1 %2 Delete %1 %2 - + Pick new color for %1 %2 Pick new color for %1 %2 @@ -546,15 +564,25 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: Pointer precision: - + Snap to grid Snap to grid + + + Open picker settings + + + + + Hide picker settings + + Settings @@ -662,87 +690,87 @@ These settings can be changed at any time from the "Settings" menu.Thanks and Contributions - LogarithmPlotter - + Source code Source code - + Original library by Raphael Graf Original library by Raphael Graf - + Source Source - + Ported to Javascript by Matthew Crumley Ported to Javascript by Matthew Crumley - - - - - + + + + + Website Website - + Ported to QMLJS by Ad5001 Ported to QMLJS by Ad5001 - + Libraries included Libraries included - + Email Email - + English English - + French French - + German German - + Hungarian Hungarian - - + + Github Github - + Norwegian Norwegian - + Translations included Translations included - + Improve Improve @@ -802,7 +830,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -844,151 +872,161 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. Cannot find property %1 of object %2. - + Undefined variable %1. Undefined variable %1. - + %1 cannot be executed. %1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). - + Unknown character "%1". Unknown character "%1". - - + + Illegal escape sequence: %1. Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 Parse error [%1:%2]: %3 - + Expected %1 Expected %1 - + Unexpected %1 Unexpected %1 - + Function definition is not permitted. Function definition is not permitted. - + Expected variable for assignment. Expected variable for assignment. - + Unexpected ".": member access is not permitted Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. Unexpected symbol: %1. - + + First argument to map is not a function. First argument to map is not a function. - + + Second argument to map is not an array. Second argument to map is not an array. - + + First argument to fold is not a function. First argument to fold is not a function. - + + Second argument to fold is not an array. Second argument to fold is not an array. - + + + First argument to filter is not a function. First argument to filter is not a function. - + + + Second argument to filter is not an array. Second argument to filter is not an array. - + + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - + + Second argument to join is not an array. Second argument to join is not an array. - + EOF End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. @@ -996,12 +1034,12 @@ These settings can be changed at any time from the "Settings" menu. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1094,7 +1132,7 @@ Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.or DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1107,7 +1145,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 8fd7ba8..08cee10 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -4,28 +4,28 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. Software de trazado 2D para diagramas de Bode, secuencias y funciones de distribución. - + Report a bug Informar de un error - + Official website Sitio web oficial @@ -33,146 +33,159 @@ AppMenuBar - + &File &Archivo - + &Load... &Abrir… - + &Save &Guardar - + Save &As... Guardar &como… - + &Quit &Salida - + &Edit &Editar - + &Undo &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + &Create &Crear - + &Settings &Ajustes - + Check for updates on startup Comprobación de las actualizaciones al arrancar - + Reset redo stack automaticly Restablecer la pila de rehacer automáticamente - + Enable LaTeX rendering Activar el renderizado de LaTeX - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + + Color Scheme + + + + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? + + BaseDialog + + + Close + + + Changelog @@ -198,42 +211,42 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -241,32 +254,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -287,23 +300,23 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) @@ -313,37 +326,42 @@ These settings can be changed at any time from the "Settings" menu. - + Enable LaTeX rendering Activar el renderizado de LaTeX - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + + Color scheme: + + + + User manual - + Changelog - + Done @@ -466,27 +484,27 @@ These settings can be changed at any time from the "Settings" menu. ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -494,15 +512,25 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid + + + Open picker settings + + + + + Hide picker settings + + Settings @@ -610,87 +638,87 @@ These settings can be changed at any time from the "Settings" menu. - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + Github - + Norwegian - + Translations included - + Improve @@ -750,7 +778,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -792,151 +820,161 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. - + Undefined variable %1. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + + First argument to map is not a function. - + + Second argument to map is not an array. - + + First argument to fold is not a function. - + + Second argument to fold is not an array. - + + + First argument to filter is not a function. - + + + Second argument to filter is not an array. - + + Second argument to indexOf is not a string or array. - + + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -944,12 +982,12 @@ These settings can be changed at any time from the "Settings" menu. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1010,7 +1048,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1019,7 +1057,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 57ec89f..40aa3a4 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -4,28 +4,28 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. Logiciel de traçage 2D pour les diagrammes de Bode, les suites et les fonctions de répartition. - + Report a bug Rapport de bug - + Official website Site officiel @@ -33,147 +33,160 @@ AppMenuBar - + &File &Fichier - + &Load... &Ouvrir… - + &Save &Sauvegarder - + Save &As... Sauvegarde &Sous… - + &Quit &Quitter - + &Edit &Édition - + &Undo &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + &Create &Créer - + &Settings &Paramètres - + Check for updates on startup Vérifier la présence de mise à jour au démarrage - + Reset redo stack automaticly Légèrement long, et pas forcément très compréhensible. Réinitialiser la pile d'action "Rétablir" automatiquement - + Enable LaTeX rendering Activer le rendu LaTeX - + Expression editor Éditeur de formule - + Automatically close parenthesises and brackets Fermer automatiquement les parenthèses et les crochets - + Enable syntax highlighting Activer la coloration syntaxique - + Enable autocompletion Activer l'autocomplétion - + + Color Scheme + + + + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? + + BaseDialog + + + Close + + + Changelog @@ -199,42 +212,42 @@ Dialog - + Edit properties of %1 %2 Changer les propriétés de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nom d'objet invalide - + An object with the name '%1' already exists. Un objet portant le nom '%1' existe déjà. - + Name Nom - + Label content Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -274,32 +287,32 @@ ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -320,54 +333,59 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenue sur LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Prenez quelques secondes pour configurer LogarithmPlotter. Ces paramètres peuvent être modifiés à tout moment à partir du menu "Paramètres". - + Enable LaTeX rendering Activer le rendu LaTeX - + Automatically close parenthesises and brackets in expressions Fermer automatiquement les parenthèses et les crochets dans les formules - + Enable syntax highlighting for expressions Activer la coloration syntaxique des formules - + Enable autocompletion interface in expression editor Activer l'interface d'autocomplétion dans l'éditeur de formules - + + Color scheme: + + + + User manual Manuel d'utilisation - + Changelog Historique des modifications - + Done Fermer @@ -378,7 +396,7 @@ These settings can always be changed at any time from the "Settings" m These settings can always be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) @@ -526,27 +544,27 @@ These settings can always be changed at any time from the "Settings" m ObjectRow - + Hide %1 %2 Cacher l'objet %1 %2 - + Show %1 %2 Montrer l'objet %1 %2 - + Set %1 %2 position Définir la position de l'objet %1 %2 - + Delete %1 %2 Supprimer l'objet %1 %2 - + Pick new color for %1 %2 Choisissez une nouvelle couleur pour %1 %2 @@ -554,15 +572,25 @@ These settings can always be changed at any time from the "Settings" m PickLocationOverlay - + Pointer precision: Précision du pointeur : - + Snap to grid Placement sur la grille + + + Open picker settings + + + + + Hide picker settings + + Settings @@ -670,87 +698,87 @@ These settings can always be changed at any time from the "Settings" m Remerciements et contributions - LogarithmPlotter - + Source code Code source - + Original library by Raphael Graf Bibliothèque originale de Raphael Graf - + Source Source - + Ported to Javascript by Matthew Crumley Porté en Javascript par Matthew Crumley - - - - - + + + + + Website Site web - + Ported to QMLJS by Ad5001 Porté à QMLJS par Ad5001 - + Libraries included Bibliothèques incluses - + Email Email - + English Anglais - + French Français - + German Allemand - + Hungarian Hongrois - - + + Github Github - + Norwegian Norvégien - + Translations included Traductions incluses - + Improve Améliorer @@ -811,7 +839,7 @@ These settings can always be changed at any time from the "Settings" m - + %1: @@ -853,151 +881,161 @@ These settings can always be changed at any time from the "Settings" m error - + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. - + Undefined variable %1. La variable %1 n'est pas définie. - + %1 cannot be executed. %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). - + Unknown character "%1". Le caractère "%1" est inconnu. - - + + Illegal escape sequence: %1. Séquence d'échappement illégale : %1. - - + + Parse error [%1:%2]: %3 Erreur de syntaxe [%1:%2] : %3 - + Expected %1 %1 attendu - + Unexpected %1 %1 inattendu - + Function definition is not permitted. La définition de fonctions n'est pas autorisée. - + Expected variable for assignment. Une variable est attendue pour l'affectation. - + Unexpected ".": member access is not permitted "." inattendu : l'accès aux propriétés n'est pas autorisé - + Unexpected "[]": arrays are disabled. "[]" inattendu : les tableaux sont désactivés. - + Unexpected symbol: %1. Symbole inconnu : %1. - + + First argument to map is not a function. Le premier argument de map n'est pas une fonction. - + + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - + + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - + + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - + + + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - + + + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - + + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - + + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. @@ -1005,12 +1043,12 @@ These settings can always be changed at any time from the "Settings" m expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe - + Error while parsing expression for property %1: %2 @@ -1103,7 +1141,7 @@ Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l&apos DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1116,7 +1154,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 70c0500..93e20ef 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -4,28 +4,28 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye - + LogarithmPlotter v%1 LogarithmPlotter %1 verzió - + 2D plotter software to make BODE plots, sequences and repartition functions. Síkbeli ábrázolásszoftver Bode-ábrák, sorozatok és eloszlási funkciók készítéséhez. - + Report a bug Hiba bejelentése - + Official website Hivatalos honlap @@ -33,146 +33,159 @@ AppMenuBar - + &File &Fájl - + &Load... &Betöltés… - + &Save &Mentés - + Save &As... Me&ntés másként… - + &Quit &Kilépés - + &Edit S&zerkesztés - + &Undo &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + &Create &Létrehozás - + &Settings &Beállítások - + Check for updates on startup Frissítések keresése indításkor - + Reset redo stack automaticly Ismétlési verem önműködő visszaállítása - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - + Expression editor Kifejezésszerkesztő - + Automatically close parenthesises and brackets Zárójelek automatikus bezárása - + Enable syntax highlighting Mondattani kiemelés engedélyezése - + Enable autocompletion Automatikus befejezés engedélyezése - + + Color Scheme + + + + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? + + BaseDialog + + + Close + + + Changelog @@ -198,42 +211,42 @@ Dialog - + Edit properties of %1 %2 %1 %2 tulajdonságainak szerkesztése - + LogarithmPlotter - Invalid object name LogarithmPlotter - Érvénytelen objektumnév - + An object with the name '%1' already exists. A(z) „%1” nevű objektum már létezik. - + Name Név - + Label content Címketartalom - + null üres - + name név - + name + value név + érték @@ -272,32 +285,32 @@ ExpressionEditor - + Object Properties Objektumtulajdonságok - + Variables Változók - + Constants Állandók - + Functions Függvények - + Executable Objects Függvényobjektumok - + Objects Objektumok @@ -318,24 +331,24 @@ GreetScreen - + Welcome to LogarithmPlotter Isten hozott a LogarithmPlotter! - + Version %1 %1 verzió - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Szánjon néhány másodpercet a LogarithmPlotter beállításához. Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + Check for updates on startup (requires online connectivity) Frissítések keresése indításkor (online kapcsolat szükséges) @@ -345,37 +358,42 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - + Automatically close parenthesises and brackets in expressions Zárójelek automatikus bezárása a kifejezésekben - + Enable syntax highlighting for expressions Mondattani kiemelés engedélyezése a kifejezésekhez - + Enable autocompletion interface in expression editor Automatikus befejezési felület engedélyezése a kifejezésszerkesztőben - + + Color scheme: + + + + User manual Használati utasítás - + Changelog Változásnapló - + Done Kész @@ -518,27 +536,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ObjectRow - + Hide %1 %2 %1 %2 elrejtése - + Show %1 %2 %1 %2 megjelenítése - + Set %1 %2 position %1 %2 helye beállítása - + Delete %1 %2 %1 %2 törlése - + Pick new color for %1 %2 Válasszon új színt a következőhöz: %1 %2 @@ -546,15 +564,25 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. PickLocationOverlay - + Pointer precision: Mutató pontossága: - + Snap to grid Rácshoz illesztés + + + Open picker settings + + + + + Hide picker settings + + Settings @@ -662,87 +690,87 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Köszönet és hozzájárulás - LogarithmPlotter - + Source code Forráskód - + Original library by Raphael Graf Eredeti könyvtár: Graf Raphael - + Source Forrás - + Ported to Javascript by Matthew Crumley JavaScript-átalakítás: Crumley Máté - - - - - + + + + + Website Honlap - + Ported to QMLJS by Ad5001 QMLJS-átalakítás: Ad5001 - + Libraries included Tartalmazott könyvtárak - + Email E-mail - + English angol - + French francia - + German német - + Hungarian magyar - - + + Github GitHub - + Norwegian norvég - + Translations included A felhasználói felület nyelvei - + Improve Fejlesztés @@ -802,7 +830,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + %1: @@ -844,151 +872,161 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - + Cannot find property %1 of object %2. A(z) %2 objektum %1 tulajdonsága nem található. - + Undefined variable %1. A(z) %1 változó nincs meghatározva. - + %1 cannot be executed. A(z) %1 nem függvény. - - - + + + Invalid expression. Érvénytelen kifejezés. - + Invalid expression (parity). Érvénytelen kifejezés (paritás). - + Unknown character "%1". Ismeretlen karakter „%1”. - - + + Illegal escape sequence: %1. Érvénytelen kilépési sorozat: %1. - - + + Parse error [%1:%2]: %3 Elemzési hiba [%1:%2]: %3 - + Expected %1 Várható %1 - + Unexpected %1 Váratlan %1 - + Function definition is not permitted. A függvény meghatározása nem engedélyezett. - + Expected variable for assignment. A hozzárendeléshez várt változó. - + Unexpected ".": member access is not permitted Váratlan „.”: a tagok hozzáférése nem engedélyezett - + Unexpected "[]": arrays are disabled. Váratlan „[]”: a tömbök le vannak tiltva. - + Unexpected symbol: %1. Váratlan szimbólum: %1. - + + First argument to map is not a function. Az első leképezési argumentum nem függvény. - + + Second argument to map is not an array. A második leképezési argumentum nem tömb. - + + First argument to fold is not a function. Az első behajtási argumentum nem függvény. - + + Second argument to fold is not an array. A második behajtási argumentum nem tömb. - + + + First argument to filter is not a function. Az első szűrési argumentum nem függvény. - + + + Second argument to filter is not an array. A második szűrési argumentum nem tömb. - + + Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. - + + Second argument to join is not an array. A második csatlakozási argumentum nem tömb. - + EOF Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. @@ -996,12 +1034,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba - + Error while parsing expression for property %1: %2 @@ -1090,7 +1128,7 @@ Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1103,7 +1141,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 32ca1b4..b47798b 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -4,28 +4,28 @@ About - + About LogarithmPlotter Om - + LogarithmPlotter v%1 LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. 2D-plotterprogramvare laget for opprettelse av Bode-diagram, sekvenser, og distribusjonsfunksjoner. - + Report a bug Rapporter en feil - + Official website @@ -33,146 +33,159 @@ AppMenuBar - + &File &Fil - + &Load... &Last inn … - + &Save &Lagre - + Save &As... Lagre &som … - + &Quit &Avslutt - + &Edit &Rediger - + &Undo &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + &Create &Opprett - + &Settings &Innstillinger - + Check for updates on startup Se etter nye versjoner ved programstart - + Reset redo stack automaticly Tilbakestill angrehistorikk automatisk - + Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + + Color Scheme + + + + &Help &Hjelp - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? + + BaseDialog + + + Close + + + Changelog @@ -198,42 +211,42 @@ Dialog - + Edit properties of %1 %2 Rediger egenskaper for %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name Navn - + Label content Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -272,32 +285,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -318,24 +331,24 @@ GreetScreen - + Welcome to LogarithmPlotter Velkommen til LogarithmPlotter - + Version %1 Versjon %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Sett opp LogarithmPlotter. Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Check for updates on startup (requires online connectivity) Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) @@ -345,37 +358,42 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Tilbakesitll angrehistorikk når en ny handling legges til - + Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + + Color scheme: + + + + User manual - + Changelog - + Done @@ -518,27 +536,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ObjectRow - + Hide %1 %2 Skjul %1 %2 - + Show %1 %2 Vis %1 %2 - + Set %1 %2 position Sett %1 %2 posisjon - + Delete %1 %2 Slett %1 %2 - + Pick new color for %1 %2 Velg ny farge for %1 %2 @@ -546,15 +564,25 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. PickLocationOverlay - + Pointer precision: Peker-presisjon: - + Snap to grid Fest til rutenett + + + Open picker settings + + + + + Hide picker settings + + Settings @@ -662,87 +690,87 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + Github - + Norwegian - + Translations included - + Improve @@ -802,7 +830,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + %1: @@ -844,151 +872,161 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.error - + Cannot find property %1 of object %2. - + Undefined variable %1. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + + First argument to map is not a function. - + + Second argument to map is not an array. - + + First argument to fold is not a function. - + + Second argument to fold is not an array. - + + + First argument to filter is not a function. - + + + Second argument to filter is not an array. - + + Second argument to indexOf is not a string or array. - + + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -996,12 +1034,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1085,7 +1123,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1094,7 +1132,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 81a2ed7..a25c5bd 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -4,28 +4,28 @@ About - + About LogarithmPlotter - + LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. - + Report a bug - + Official website @@ -33,146 +33,159 @@ AppMenuBar - + &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Create - + &Settings - + Check for updates on startup - + Reset redo stack automaticly - + Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + + Color Scheme + + + + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? + + BaseDialog + + + Close + + + Changelog @@ -198,42 +211,42 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -241,32 +254,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -287,23 +300,23 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) @@ -313,37 +326,42 @@ These settings can be changed at any time from the "Settings" menu. - + Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + + Color scheme: + + + + User manual - + Changelog - + Done @@ -466,27 +484,27 @@ These settings can be changed at any time from the "Settings" menu. ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -494,15 +512,25 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid + + + Open picker settings + + + + + Hide picker settings + + Settings @@ -610,87 +638,87 @@ These settings can be changed at any time from the "Settings" menu. - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + Github - + Norwegian - + Translations included - + Improve @@ -750,7 +778,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -792,151 +820,161 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. - + Undefined variable %1. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + + First argument to map is not a function. - + + Second argument to map is not an array. - + + First argument to fold is not a function. - + + Second argument to fold is not an array. - + + + First argument to filter is not a function. - + + + Second argument to filter is not an array. - + + Second argument to indexOf is not a string or array. - + + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -944,12 +982,12 @@ These settings can be changed at any time from the "Settings" menu. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1010,7 +1048,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1019,7 +1057,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} From 37150b5823b56efebd589c0db9fce5ec50773e53 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 06:18:03 +0200 Subject: [PATCH 096/436] Fixing CI image --- ci/drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/drone.yml b/ci/drone.yml index 591934e..710c96c 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -21,7 +21,7 @@ steps: event: [ push, tag ] - name: Windows test - image: ad5001/ubuntu-pyside6-xvfb-wine:jammy-6.5.0 + image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0 commands: - # For some reason, launching GUI apps with wine, even with xvfb-run, fails. - xvfb-run python run.py --test-build --no-check-for-updates From 0ac690d0c1b6d08aa6eef37fc8e9406bdfbcc228 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 07:22:33 +0200 Subject: [PATCH 097/436] Fixing cursor from expression editor. --- .../LogarithmPlotter/Setting/ExpressionEditor.qml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 1735278..897abda 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -206,7 +206,7 @@ Item { verticalAlignment: TextInput.AlignVCenter horizontalAlignment: control.label == "" ? TextInput.AlignLeft : TextInput.AlignHCenter text: control.defValue - color: syntaxHighlightingEnabled ? "transparent" : sysPalette.windowText + color: syntaxHighlightingEnabled ? sysPalette.window : sysPalette.windowText focus: true selectByMouse: true @@ -229,8 +229,6 @@ Item { } } - //onTextEdited: acPopupContent.itemSelected = 0 - onActiveFocusChanged: { if(activeFocus && autocompleteEnabled) autocompletePopup.open() @@ -238,6 +236,12 @@ Item { autocompletePopup.close() } + cursorDelegate: Rectangle { + visible: editor.cursorVisible + color: sysPalette.windowText + width: editor.cursorRectangle.width + } + Keys.onUpPressed: function(event) { if(autocompleteEnabled) if(acPopupContent.itemSelected == 0) From b143f7e10d75833e8ca05fdf76b767f46d7e00d2 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 07:29:15 +0200 Subject: [PATCH 098/436] Disable Windows testing (issue between PySide6, wine & Xvfb). Reinstating windows building. --- ci/drone.yml | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 710c96c..3c69c83 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -20,30 +20,29 @@ steps: when: event: [ push, tag ] -- name: Windows test - image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0 - commands: - - # For some reason, launching GUI apps with wine, even with xvfb-run, fails. - - xvfb-run python run.py --test-build --no-check-for-updates - - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test1.lpf - - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test2.lpf - when: - event: [ push, tag ] - +# - name: Windows test +# image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0 +# commands: +# - # For some reason, launching GUI apps with wine, even with xvfb-run, fails. +# - xvfb-run python run.py --test-build --no-check-for-updates +# - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test1.lpf +# - xvfb-run python run.py --test-build --no-check-for-updates ./ci/test2.lpf +# when: +# event: [ push, tag ] # - name: Linux packaging -# image: ad5001/accountfree-build-img:hirsute-5.15.2 +# image: ad5001/ubuntu-pyside6-xvfb:jammy-6.5.0 # commands: # - bash scripts/package-linux.sh # when: # event: [ push, tag ] -# -# -# - name: Windows building -# image: ad5001/accountfree-build-img-wine:win7-5.15.2 -# commands: -# - bash scripts/build-wine.sh -# - bash scripts/package-wine.sh -# when: -# event: [ push, tag ] -# + + +- name: Windows building + image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0 + commands: + - bash scripts/build-wine.sh + - bash scripts/package-wine.sh + when: + event: [ push, tag ] + From 4be92a07e3932d7079c36a668af5552625814722 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 07:43:44 +0200 Subject: [PATCH 099/436] Adding revision to CI building image. --- ci/drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 3c69c83..6dd5beb 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -21,7 +21,7 @@ steps: event: [ push, tag ] # - name: Windows test -# image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0 +# image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0-rev1 # commands: # - # For some reason, launching GUI apps with wine, even with xvfb-run, fails. # - xvfb-run python run.py --test-build --no-check-for-updates @@ -39,7 +39,7 @@ steps: - name: Windows building - image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0 + image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0-rev1 commands: - bash scripts/build-wine.sh - bash scripts/package-wine.sh From d8534d1e0d7eb2662d1a92231ea2494a24a9ec3c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 09:31:43 +0200 Subject: [PATCH 100/436] Adding bottom borders to dialogs --- .../LogarithmPlotter/History/HistoryItem.qml | 2 -- .../ad5001/LogarithmPlotter/Popup/Changelog.qml | 13 ++++++++++++- .../ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 15 +++++++++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index bb4b60b..67a7431 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -132,8 +132,6 @@ Button { color: sysPalette.windowText } - //text: content - ToolTip.visible: hovered ToolTip.delay: 200 ToolTip.text: content diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index b7efb83..0288b8a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -74,12 +74,23 @@ Popup { } } + Rectangle { + id: bottomSeparator + opacity: 0.3 + color: sysPalette.windowText + width: parent.width * 2 / 3 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: doneBtn.top + anchors.bottomMargin: 7 + } + Button { id: doneBtn text: qsTr("Done") font.pixelSize: 18 anchors.bottom: parent.bottom - anchors.bottomMargin: 10 + anchors.bottomMargin: 7 anchors.horizontalCenter: parent.horizontalCenter onClicked: changelogPopup.close() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index e9ae5f1..b3aa12b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -187,11 +187,22 @@ Popup { } } } - + + Rectangle { + id: bottomSeparator + opacity: 0.3 + color: sysPalette.windowText + width: parent.width * 2 / 3 + height: 1 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: bottomButtons.top + anchors.bottomMargin: 9 + } + Row { id: bottomButtons anchors.bottom: parent.bottom - anchors.bottomMargin: 10 + anchors.bottomMargin: 7 spacing: 10 anchors.horizontalCenter: parent.horizontalCenter From 20c1ed005ee97e734b5e8effd0a4fa1b852ce521 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 09:49:20 +0200 Subject: [PATCH 101/436] Removing warning --- .../eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 8c5fa9a..f869177 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -61,8 +61,6 @@ Popup.BaseDialog { minimumHeight: Math.max(450,dlgProperties.height + margin*4 + 30) maximumHeight: minimumHeight - // Disable closing on return/enter, causing issues with autocomplete. - // onActionChosen: if(action.key == Qt.Key_Enter || action.key == Qt.Key_Return) action.accepted = false Item { anchors { top: parent.top; @@ -77,7 +75,7 @@ Popup.BaseDialog { Column { id: dlgProperties - anchors.top: dlgTitle.bottom + anchors.top: parent.top width: objEditor.width - 20 spacing: 10 From 7a80455e2512697b46222821d48203d365706b7e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 22 May 2023 11:02:34 +0200 Subject: [PATCH 102/436] Fixing the usage of symbols in text. --- .../ad5001/LogarithmPlotter/js/math/latex.js | 20 ++++++++++++------- .../ad5001/LogarithmPlotter/js/objs/text.js | 19 +++++++++++------- LogarithmPlotter/util/latex.py | 6 ++---- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 69b7d8c..39461fd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -100,10 +100,11 @@ function functionToLatex(f, args) { /** * Creates a latex variable from a variable. * - * @param {string} vari - variable to convert + * @param {string} vari - variable text to convert + * @param {bool} wrapIn$ - checks whether the escaped chars should be escaped * @returns {string} */ -function variable(vari) { +function variable(vari, wrapIn$ = false) { let unicodechars = ["α","β","γ","δ","ε","ζ","η", "π","θ","κ","λ","μ","ξ","ρ", "ς","σ","τ","φ","χ","ψ","ω", @@ -124,11 +125,16 @@ function variable(vari) { "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", "\\pi"] - for(let i = 0; i < unicodechars.length; i++) { - //console.log(vari, unicodechars[i], equivalchars[i]); - if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i]) - } + if(wrapIn$) + for(let i = 0; i < unicodechars.length; i++) { + if(vari.includes(unicodechars[i])) + vari = vari.replace(new RegExp(unicodechars[i], 'g'), '$'+equivalchars[i]+'$') + } + else + for(let i = 0; i < unicodechars.length; i++) { + if(vari.includes(unicodechars[i])) + vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i]) + } return vari; } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index 11ac049..2e16fa9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -59,16 +59,21 @@ class Text extends Common.DrawableObject { } latexMarkupText() { - let txt = Latex.variable(this.text) + // Check whether the text contains latex escaped elements. + let txt = [] + this.text.split('$$').forEach(function(t) { txt = txt.concat(Latex.variable(t, true).replace(/\$\$/g, '').split('$')) }) + let newTxt = txt[0] let i - for(i = 0; txt.includes('$$'); i++) + // Split between normal text and latex escaped. + for(i = 0; i < txt.length-1; i++) if(i & 0x01) // Every odd number - txt = txt.replace('$$', '\\textsf{') + newTxt += '\\textsf{'+Latex.variable(txt[i+1]) else - txt = txt.replace('$$', '}') - if(i & 0x01) // Finished by a } - txt += "{" - return txt + newTxt += '}'+txt[i+1] + // Finished by a } + if(i & 0x01) + newTxt += "{" + return newTxt } getLatexString() { diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index e2d9823..d5e362e 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -35,7 +35,6 @@ If not found, it will send an alert to the user. """ LATEX_PATH = which('latex') DVIPNG_PATH = which('dvipng') -#subprocess.run(["ls", "-l", "/dev/null"], capture_output=True) DEFAULT_LATEX_DOC = Template(r""" \documentclass[]{minimal} @@ -85,7 +84,7 @@ class Latex(QObject): """ Prepares and renders a latex string into a png file. """ - markup_hash = hash(latex_markup) + markup_hash = "render"+str(hash(latex_markup)) export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}') if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) @@ -119,14 +118,13 @@ class Latex(QObject): def convert_latex_to_dvi(self, export_path: str): """ - Converts a DVI file to a PNG file. + Converts a TEX file to a DVI file. """ self.run([ LATEX_PATH, export_path + ".tex" ]) - def convert_dvi_to_png(self, dvi_path: str, export_path: str, font_size: float, color: QColor): """ Converts a DVI file to a PNG file. From 3904dc0217ce16ee4305d45e48976272713a0469 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 23 May 2023 12:42:43 +0200 Subject: [PATCH 103/436] Removing last instances of PySide2, updating copyrights & version to v0.4 --- README.md | 2 +- linux/debian/control | 2 +- linux/debian/copyright | 2 +- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 2 +- mac/Info.plist | 2 +- scripts/package-macosx.sh | 2 +- win/installer.nsi | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f3dc862..e75daba 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ In order to test translations, you can use the `--lang=` command line All scripts noted here can be found in the `scripts` directory. You can generate installers from LogarithmPlotter after installing all the dependencies: -For all builds, you need [Python 3](https://python.org) with [PySide2](https://pypi.org/project/PySide2/) installable with `pip install PySide2`. +For all builds, you need [Python 3](https://python.org) with [PySide6](https://pypi.org/project/PySide6/) installable with `pip install PySide6`. - Windows installer: - You need `pyinstaller`. You can install it using `pip install pyinstaller`. - Run the `build-windows.bat` script (or `build-wine.sh` if you're cross-compiling with wine on Linux) to build an exe for LogarithmPlotter. diff --git a/linux/debian/control b/linux/debian/control index 81cbfdf..82b3fcd 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -1,6 +1,6 @@ Package: logarithmplotter Source: logarithmplotter -Version: 0.3.0 +Version: 0.4.0 Architecture: all Maintainer: Ad5001 Depends: python3, python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), texlive-latex-base, dvipng diff --git a/linux/debian/copyright b/linux/debian/copyright index 2d22f6e..6d05e77 100644 --- a/linux/debian/copyright +++ b/linux/debian/copyright @@ -3,6 +3,6 @@ Upstream-Name: logarithmplotter Upstream-Contact: Ad5001 Files: * -Copyright: 2022, Ad5001 +Copyright: 2023, Ad5001 License: GPL-3.0+ diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 28d5d83..9c8f3a8 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -1,5 +1,5 @@ - + eu.ad5001.LogarithmPlotter eu.ad5001.LogarithmPlotter.desktop diff --git a/mac/Info.plist b/mac/Info.plist index dbbe631..22fdeca 100644 --- a/mac/Info.plist +++ b/mac/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.3.0 + 0.4.0 NSHighResolutionCapable UTExportedTypeDeclarations diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index 019cf2b..bae5c03 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -VERSION=0.3.0 +VERSION=0.4.0 title="LogarithmPlotter v${VERSION} Setup" finalDMGName="LogarithmPlotter-v${VERSION}-setup.dmg" applicationName=LogarithmPlotter diff --git a/win/installer.nsi b/win/installer.nsi index 2d82a83..45f61c8 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -11,9 +11,9 @@ Unicode True !define PROG_ID "LogarithmPlotter.File.1" !define DEV_NAME "Ad5001" !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" -!define VERSION_SHORT "0.3.0" +!define VERSION_SHORT "0.4.0" !define APP_VERSION "${VERSION_SHORT}.0" -!define COPYRIGHT "Ad5001 (c) 2022" +!define COPYRIGHT "Ad5001 (c) 2023" !define DESCRIPTION "Create graphs with logarithm scales." !define REG_UNINSTALL "Software\Microsoft\Windows\CurrentVersion\Uninstall\LogarithmPlotter" @@ -163,7 +163,7 @@ Section "" File *.bmp File *.ico File /r qml - File /r PySide2 + File /r PySide6 File /r shiboken2 From fce2a5ba0d45138cfba06f2ef6f390b10e4e5cda Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 23 May 2023 12:51:47 +0200 Subject: [PATCH 104/436] Adding version freeze for changelog --- LogarithmPlotter/util/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index 8cf7891..8b28ecc 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -40,7 +40,7 @@ class ChangelogFetcher(QRunnable): msg_text = "Unknown changelog error." try: # Fetching version - r = urlopen("https://api.ad5001.eu/changelog/logarithmplotter/") + r = urlopen("https://api.ad5001.eu/changelog/logarithmplotter/?version=" + __VERSION__) lines = r.readlines() r.close() msg_text = "".join(map(lambda x: x.decode('utf-8'), lines)).strip() From 82d53748b3c6a4de6b25cc800ee2e95592f5552e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 23 May 2023 13:03:00 +0200 Subject: [PATCH 105/436] Forgot to change shiboken2 to shiboken6 in windows installer. --- win/installer.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/installer.nsi b/win/installer.nsi index 45f61c8..395aa6b 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -164,7 +164,7 @@ Section "" File *.ico File /r qml File /r PySide6 - File /r shiboken2 + File /r shiboken6 CreateShortcut "$SMPROGRAMS\LogarithmPlotter.lnk" "$INSTDIR\logarithmplotter.exe" From abae3ef94bcecdbd20040c9d76a461cb3a3cc93d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 23 May 2023 12:06:49 +0000 Subject: [PATCH 106/436] Translated using Weblate (English) Currently translated at 100.0% (258 of 258 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 299eee8..30ff25f 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -125,7 +125,7 @@ Color Scheme - + Color Scheme @@ -183,7 +183,7 @@ Close - + Close @@ -380,7 +380,7 @@ These settings can be changed at any time from the "Settings" menu. Color scheme: - + Color scheme: @@ -576,12 +576,12 @@ These settings can be changed at any time from the "Settings" menu. Open picker settings - + Open picker settings Hide picker settings - + Hide picker settings From ae930be62157fd7b4fb53decb8130086205772ff Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 23 May 2023 12:10:30 +0000 Subject: [PATCH 107/436] Translated using Weblate (German) Currently translated at 100.0% (258 of 258 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 970bc48..1778019 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -125,7 +125,7 @@ Color Scheme - + Syntaktische Färbung @@ -183,7 +183,7 @@ Close - + Schließen @@ -380,7 +380,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Color scheme: - + Syntaktische Färbung Thema: @@ -576,12 +576,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Open picker settings - + Zeigereinstellungen öffnen Hide picker settings - + Zeigereinstellungen ausblenden From 3da51430f15475fa54d54cf12b2734bd6756d886 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 23 May 2023 12:08:36 +0000 Subject: [PATCH 108/436] Translated using Weblate (French) Currently translated at 100.0% (258 of 258 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 40aa3a4..683bf8d 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -126,7 +126,7 @@ Color Scheme - + Coloration Syntaxique @@ -184,7 +184,7 @@ Close - + Fermer @@ -372,7 +372,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Color scheme: - + Thème de coloration syntaxique : @@ -584,12 +584,12 @@ These settings can always be changed at any time from the "Settings" m Open picker settings - + Ouvrir les paramètres du pointeur Hide picker settings - + Cacher les paramètres du pointeur From d6dee6a2be4b92aa5e0520e20ab3a6dcbb5893ce Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 02:48:35 +0200 Subject: [PATCH 109/436] Fixing color picker not working --- .../qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index c5e2918..81374d4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -199,9 +199,9 @@ Item { title: qsTr("Pick new color for %1 %2").arg(obj.constructor.displayType()).arg(obj.name) onAccepted: { history.addToHistory(new HistoryLib.ColorChanged( - obj.name, obj.type, obj.color, color.toString() + obj.name, obj.type, obj.color, selectedColor.toString() )) - obj.color = color.toString() + obj.color = selectedColor.toString() changed() } } From 5cef8e23fa8ba6cb38dfef4399f516da4ddc55c6 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 03:17:21 +0200 Subject: [PATCH 110/436] Fixing several issues with repartition + Underscores being automatically removed from the name the moment it's edited. + Fixing issue with function name change. --- .../LogarithmPlotter/ObjectLists/Editor/Dialog.qml | 1 + .../ad5001/LogarithmPlotter/Setting/TextSetting.qml | 3 ++- .../ad5001/LogarithmPlotter/js/objs/repartition.js | 12 ++++++------ .../qml/eu/ad5001/LogarithmPlotter/js/utils.js | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index f869177..6cdc6a4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -106,6 +106,7 @@ Popup.BaseDialog { value: objEditor.obj.name onChanged: function(newValue) { let newName = Utils.parseName(newValue) + console.log(newValue, newName) if(newName != '' && objEditor.obj.name != newName) { if(newName in Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 2c6ea9a..6e8ff1d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -119,12 +119,13 @@ Item { focus: true text: control.defValue selectByMouse: true - onEditingFinished: { + onEditingFinished: function() { if(insertButton.focus || insertPopup.focus) return var value = text if(control.isInt) value = Math.max(control.min,parseInt(value).toString()=="NaN"?control.min:parseInt(value)) if(control.isDouble) value = Math.max(control.min,parseFloat(value).toString()=="NaN"?control.min:parseFloat(value)) if(value != "" && value.toString() != defValue) { + console.log(value, value.toString()) control.changed(value) defValue = value.toString() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js index 7a98b56..c8a30a5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js @@ -96,14 +96,14 @@ class RepartitionFunction extends Common.ExecutableObject { draw(canvas, ctx) { var currentY = 0; var keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b) - if(canvas.visible(keys[0],this.probabilities[keys[0]].replace(/,/g, '.'))) { + if(canvas.isVisible(keys[0],this.probabilities[keys[0]].replace(/,/g, '.'))) { canvas.drawLine(ctx, 0, canvas.y2px(0), canvas.x2px(keys[0]), canvas.y2px(0) ) - if(canvas.visible(keys[0],0)) { + if(canvas.isVisible(keys[0],0)) { ctx.beginPath(); ctx.arc(canvas.x2px(keys[0])+4,canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2); ctx.stroke(); @@ -112,26 +112,26 @@ class RepartitionFunction extends Common.ExecutableObject { for(var i = 0; i < keys.length-1; i++) { var idx = keys[i]; currentY += parseFloat(this.probabilities[idx].replace(/,/g, '.')); - if(canvas.visible(idx,currentY) || canvas.visible(keys[i+1],currentY)) { + if(canvas.isVisible(idx,currentY) || canvas.isVisible(keys[i+1],currentY)) { canvas.drawLine(ctx, Math.max(0,canvas.x2px(idx)), canvas.y2px(currentY), Math.min(canvas.canvasSize.width,canvas.x2px(keys[i+1])), canvas.y2px(currentY) ) - if(canvas.visible(idx,currentY)) { + if(canvas.isVisible(idx,currentY)) { ctx.beginPath(); ctx.arc(canvas.x2px(idx),canvas.y2px(currentY), 4, 0, 2 * Math.PI); ctx.fill(); } - if(canvas.visible(keys[i+1],currentY)) { + if(canvas.isVisible(keys[i+1],currentY)) { ctx.beginPath(); ctx.arc(canvas.x2px(keys[i+1])+4,canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2); ctx.stroke(); } } } - if(canvas.visible(keys[keys.length-1],currentY+parseFloat(this.probabilities[keys[keys.length-1]]))) { + if(canvas.isVisible(keys[keys.length-1],currentY+parseFloat(this.probabilities[keys[keys.length-1]]))) { canvas.drawLine(ctx, Math.max(0,canvas.x2px(keys[keys.length-1])), canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))), diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index 466fc9f..ee53afa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -316,8 +316,8 @@ function parseName(str, removeUnallowed = true) { [/([^a-z]|^)gps(i)?([^a-z]|$)/g, '$1Ψ$3'], [/([^a-z]|^)gom(ega)?([^a-z]|$)/g, '$1Ω$3'], // Underscores - [/_\(([^_]+)\)/g, function(match, p1) { return textsub(p1) }], - [/_([^" ]+)/g, function(match, p1) { return textsub(p1) }], + // [/_\(([^_]+)\)/g, function(match, p1) { return textsub(p1) }], + // [/_([^" ]+)/g, function(match, p1) { return textsub(p1) }], // Array elements [/\[([^\]\[]+)\]/g, function(match, p1) { return textsub(p1) }], // Removing From 6abbbe5e61518ab5158c7135140c4f087222a4ab Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 03:51:42 +0200 Subject: [PATCH 111/436] Adding picker for properties (x,y,labelX) --- .../ObjectLists/Editor/CustomPropertyList.qml | 107 +++++++++++++----- .../ObjectLists/Editor/Dialog.qml | 7 +- .../ObjectLists/ObjectLists.qml | 2 + .../LogarithmPlotter/Setting/TextSetting.qml | 1 - 4 files changed, 84 insertions(+), 33 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 8c74403..0551d2e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -18,6 +18,7 @@ import QtQuick import QtQuick.Controls +import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import "../../js/objects.js" as Objects import "../../js/historylib.js" as HistoryLib @@ -43,6 +44,11 @@ Repeater { Object whose properties to list and edit. */ property var obj + /*! + \qmlproperty var CustomPropertyList::positionPicker + Reference to the global PositionPicker QML object. + */ + property var positionPicker readonly property var textTypes: ['Domain', 'string', 'number'] readonly property var comboBoxTypes: ['ObjectType', 'Enum'] @@ -94,7 +100,7 @@ Repeater { // Setting for text & number settings as well as domains Setting.TextSetting { - height: 30 + height: 30 label: propertyLabel icon: `settings/custom/${propertyIcon}.svg` isDouble: propertyType == 'number' @@ -123,15 +129,15 @@ Repeater { } - // D.MessageDialog { - // id: parsingErrorDialog - // title: qsTranslate("expression", "LogarithmPlotter - Parsing error") - // text: "" - // function showDialog(propName, propValue, error) { - // text = qsTranslate("error", "Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3").arg(propName).arg(error).arg(propValue) - // open() - // } - // } + Native.MessageDialog { + id: parsingErrorDialog + title: qsTranslate("expression", "LogarithmPlotter - Parsing error") + text: "" + function showDialog(propName, propValue, error) { + text = qsTranslate("error", "Error while parsing expression for property %1:\n%2\n\nEvaluated expression: %3").arg(propName).arg(error).arg(propValue) + open() + } + } } } @@ -255,29 +261,68 @@ Repeater { } delegate: Component { - Loader { - //height: customPropComment.height + customPropText.height + customPropCheckBox.height + customPropCombo.height + customPropListDict.height + Row { width: dlgProperties.width - property string propertyName: modelData[0] - property var propertyType: modelData[1] - property string propertyLabel: qsTranslate('prop',propertyName) - property string propertyIcon: Utils.camelCase2readable(propertyName) + spacing: 5 - sourceComponent: { - if(propertyName.startsWith('comment')) - return commentComponent - else if(propertyType == 'boolean') - return checkboxComponent - else if(paramTypeIn(propertyType, ['Expression'])) - return expressionEditorComponent - else if(paramTypeIn(propertyType, textTypes)) - return textEditorComponent - else if(paramTypeIn(propertyType, comboBoxTypes)) - return comboBoxComponent - else if(paramTypeIn(propertyType, listTypes)) - return listDictEditorComponent - else - return {} + Loader { + id: propertyEditor + width: dlgProperties.width - pointerButton.width + property string propertyName: modelData[0] + property var propertyType: modelData[1] + property string propertyLabel: qsTranslate('prop',propertyName) + property string propertyIcon: Utils.camelCase2readable(propertyName) + + sourceComponent: { + if(propertyName.startsWith('comment')) + return commentComponent + else if(propertyType == 'boolean') + return checkboxComponent + else if(paramTypeIn(propertyType, ['Expression'])) + return expressionEditorComponent + else if(paramTypeIn(propertyType, textTypes)) + return textEditorComponent + else if(paramTypeIn(propertyType, comboBoxTypes)) + return comboBoxComponent + else if(paramTypeIn(propertyType, listTypes)) + return listDictEditorComponent + else + return {} + } + } + + Button { + id: pointerButton + height: parent.height + width: visible ? height : 0 + anchors.verticalCenter: parent.verticalCenter + + property bool isXProp: ['labelX', 'x'].includes(propertyEditor.propertyName) + property bool isYProp: ['y'].includes(propertyEditor.propertyName) + visible: isXProp || isYProp + ToolTip.visible: hovered + ToolTip.text: qsTr("Pick on graph") + + Setting.Icon { + id: icon + width: 18 + height: 18 + anchors.centerIn: parent + + color: sysPalette.windowText + source: '../icons/common/position.svg' + } + + onClicked: { + positionPicker.objType = objType + positionPicker.objName = obj.name + positionPicker.pickX = isXProp + positionPicker.pickY = isYProp + positionPicker.propertyX = propertyEditor.propertyName + positionPicker.propertyY = propertyEditor.propertyName + positionPicker.visible = true + objEditor.close() + } } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 6cdc6a4..a9b8052 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -55,6 +55,11 @@ Popup.BaseDialog { Instance of the object being edited. */ property var obj: Objects.currentObjects[objType][objIndex] + /*! + \qmlproperty var EditorDialog::posPicker + Reference to the global PositionPicker QML object. + */ + property var posPicker title: "LogarithmPlotter" width: 350 @@ -106,7 +111,6 @@ Popup.BaseDialog { value: objEditor.obj.name onChanged: function(newValue) { let newName = Utils.parseName(newValue) - console.log(newValue, newName) if(newName != '' && objEditor.obj.name != newName) { if(newName in Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) @@ -144,6 +148,7 @@ Popup.BaseDialog { CustomPropertyList { id: dlgCustomProperties obj: objEditor.obj + positionPicker: posPicker onChanged: { obj.update() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 4fa963d..a964d94 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -116,6 +116,8 @@ ScrollView { // Object editor Editor.Dialog { id: objEditor + + posPicker: positionPicker } /*! diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 6e8ff1d..539ea96 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -125,7 +125,6 @@ Item { if(control.isInt) value = Math.max(control.min,parseInt(value).toString()=="NaN"?control.min:parseInt(value)) if(control.isDouble) value = Math.max(control.min,parseFloat(value).toString()=="NaN"?control.min:parseFloat(value)) if(value != "" && value.toString() != defValue) { - console.log(value, value.toString()) control.changed(value) defValue = value.toString() } From d1843b455aa1a1411c9fbeb5cf99e5472a4ad2af Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 03:58:13 +0200 Subject: [PATCH 112/436] Fixing issue with sums & latex variables. --- .../qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js index b9e04ce..f132f47 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js @@ -54,7 +54,7 @@ class SommeGainsBode extends Common.ExecutableObject { } getLatexString() { - return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Gain Bode').map(Latex.variable).join(' + ')}` + return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Gain Bode').map(name => Latex.variable(name)).join(' + ')}` } execute(x = 0) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js index 8f16693..b9abafd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js @@ -53,7 +53,7 @@ class SommePhasesBode extends Common.ExecutableObject { } getLatexString() { - return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Phase Bode').map(Latex.variable).join(' + ')}` + return `${Latex.variable(this.name)} = ${Objects.getObjectsName('Phase Bode').map(name => Latex.variable(name)).join(' + ')}` } execute(x=1) { From f7dd40d2f5ef5d167b72d5d53d9114cbfd1ad56d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 04:00:09 +0200 Subject: [PATCH 113/436] Changing omega zero icon file name to fix issue with finding it. --- .../icons/settings/custom/{ω₀.svg => ω_0.svg} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/{ω₀.svg => ω_0.svg} (100%) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/ω₀.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/ω_0.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/ω₀.svg rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/custom/ω_0.svg From 016a21ecb4612f4e5be70ae6550e4d04870c482c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 04:18:55 +0200 Subject: [PATCH 114/436] Adding new translations --- LogarithmPlotter/i18n/lp_de.ts | 75 +++++++++++++++++----------- LogarithmPlotter/i18n/lp_en.ts | 75 +++++++++++++++++----------- LogarithmPlotter/i18n/lp_es.ts | 72 +++++++++++++++----------- LogarithmPlotter/i18n/lp_fr.ts | 75 +++++++++++++++++----------- LogarithmPlotter/i18n/lp_hu.ts | 75 +++++++++++++++++----------- LogarithmPlotter/i18n/lp_nb_NO.ts | 72 +++++++++++++++----------- LogarithmPlotter/i18n/lp_template.ts | 72 +++++++++++++++----------- 7 files changed, 313 insertions(+), 203 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 1778019..86dccae 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -194,7 +194,7 @@ Changelog abrufen… - + Done Schließen @@ -202,51 +202,56 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen + + + Pick on graph + + Dialog - + Edit properties of %1 %2 Eigenschaften von %1 %2 bearbeiten - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ungültiger Objektname - + An object with the name '%1' already exists. Ein Objekt mit dem Namen '%1' existiert bereits. - + Name Name - + Label content Etikett - + null leer - + name Name - + name + value Name + Wert @@ -285,32 +290,32 @@ ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktion - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -383,17 +388,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Syntaktische Färbung Thema: - + User manual Benutzerhandbuch - + Changelog Changelog - + Done Schließen @@ -1006,34 +1011,46 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + Fehler beim Analysieren des Ausdrucks für die Eigenschaft %1: +%2 + +Ausdruck analysiert: %3 + expression + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler @@ -1118,7 +1135,7 @@ Ausdruck analysiert: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1127,12 +1144,12 @@ Wenn Sie bereits eine LaTeX-Distribution installiert haben, vergewissern Sie sic Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.org/texlive/ herunterladen. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1145,7 +1162,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 30ff25f..711f2cc 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -194,7 +194,7 @@ Fetching changelog… - + Done Done @@ -202,51 +202,56 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 + + + Pick on graph + + Dialog - + Edit properties of %1 %2 Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. An object with the name '%1' already exists. - + Name Name - + Label content Label content - + null null - + name name - + name + value name + value @@ -285,32 +290,32 @@ ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -383,17 +388,17 @@ These settings can be changed at any time from the "Settings" menu.Color scheme: - + User manual User manual - + Changelog Changelog - + Done Done @@ -1006,34 +1011,46 @@ These settings can be changed at any time from the "Settings" menu.End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + expression + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error @@ -1118,7 +1135,7 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1127,12 +1144,12 @@ If you already have a LaTeX distribution installed, make sure it's installe Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1145,7 +1162,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 08cee10..a6ccaec 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -194,7 +194,7 @@ - + Done @@ -202,51 +202,56 @@ CustomPropertyList - - + + + Create new %1 + + + Pick on graph + + Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -254,32 +259,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -351,17 +356,17 @@ These settings can be changed at any time from the "Settings" menu. - + User manual - + Changelog - + Done @@ -954,34 +959,43 @@ These settings can be changed at any time from the "Settings" menu. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + expression + LogarithmPlotter - Parsing error @@ -1036,19 +1050,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1057,7 +1071,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 683bf8d..70fd443 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -195,7 +195,7 @@ Récupération de l'historique des modifications… - + Done Fermer @@ -203,51 +203,56 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 + + + Pick on graph + + Dialog - + Edit properties of %1 %2 Changer les propriétés de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nom d'objet invalide - + An object with the name '%1' already exists. Un objet portant le nom '%1' existe déjà. - + Name Nom - + Label content Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -287,32 +292,32 @@ ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -375,17 +380,17 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P Thème de coloration syntaxique : - + User manual Manuel d'utilisation - + Changelog Historique des modifications - + Done Fermer @@ -1015,34 +1020,46 @@ These settings can always be changed at any time from the "Settings" m Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + Erreur lors de l'analyse de la formule pour la propriété %1 : +%2 + +Formule analysée : %3 + expression + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe @@ -1127,7 +1144,7 @@ Formule analysée : %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1136,12 +1153,12 @@ Si vous avez déjà installé une distribution LaTeX, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1154,7 +1171,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 93e20ef..355b65a 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -194,7 +194,7 @@ Változásnapló lekérése… - + Done Kész @@ -202,51 +202,56 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása + + + Pick on graph + + Dialog - + Edit properties of %1 %2 %1 %2 tulajdonságainak szerkesztése - + LogarithmPlotter - Invalid object name LogarithmPlotter - Érvénytelen objektumnév - + An object with the name '%1' already exists. A(z) „%1” nevű objektum már létezik. - + Name Név - + Label content Címketartalom - + null üres - + name név - + name + value név + érték @@ -285,32 +290,32 @@ ExpressionEditor - + Object Properties Objektumtulajdonságok - + Variables Változók - + Constants Állandók - + Functions Függvények - + Executable Objects Függvényobjektumok - + Objects Objektumok @@ -383,17 +388,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + User manual Használati utasítás - + Changelog Változásnapló - + Done Kész @@ -1006,34 +1011,46 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + Hiba a(z) %1 tulajdonság kifejezésének elemzésekor: +%2 + +Kiértékelt kifejezés: %3 + expression + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba @@ -1114,7 +1131,7 @@ Kiértékelt kifejezés: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1123,12 +1140,12 @@ Ha már telepítve van egy LaTeX disztribúció, győződjön meg arról, hogy a Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https://tug.org/texlive/ címről. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1141,7 +1158,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index b47798b..1181e93 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -194,7 +194,7 @@ - + Done @@ -202,51 +202,56 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 + + + Pick on graph + + Dialog - + Edit properties of %1 %2 Rediger egenskaper for %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name Navn - + Label content Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -285,32 +290,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -383,17 +388,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + User manual - + Changelog - + Done @@ -1006,34 +1011,43 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + expression + LogarithmPlotter - Parsing error @@ -1111,19 +1125,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1132,7 +1146,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index a25c5bd..ffda6b0 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -194,7 +194,7 @@ - + Done @@ -202,51 +202,56 @@ CustomPropertyList - - + + + Create new %1 + + + Pick on graph + + Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -254,32 +259,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -351,17 +356,17 @@ These settings can be changed at any time from the "Settings" menu. - + User manual - + Changelog - + Done @@ -954,34 +959,43 @@ These settings can be changed at any time from the "Settings" menu. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. + + + Error while parsing expression for property %1: +%2 + +Evaluated expression: %3 + + expression + LogarithmPlotter - Parsing error @@ -1036,19 +1050,19 @@ Evaluated expression: %3 latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1057,7 +1071,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} From 75e70903f1e4582f44c3fe002e6ebec5e6ebd662 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 06:47:34 +0200 Subject: [PATCH 115/436] Fixing coloration in dark theme of autocomplete categories. --- .../ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index df2f9f3..d5cc9af 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -84,11 +84,12 @@ ListView { Text { leftPadding: 5 text: listFiltered.category + color: sysPalette.windowText } Rectangle { height: 1 - color: 'black' + color: 'gray' width: parent.width } } From 35ce1c4824148e435bd4cce3d7c5a10a75450612 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 07:03:12 +0200 Subject: [PATCH 116/436] Adding error handling for function argument errors. --- LogarithmPlotter/i18n/lp_de.ts | 13 +++++++++++ LogarithmPlotter/i18n/lp_en.ts | 13 +++++++++++ LogarithmPlotter/i18n/lp_es.ts | 13 +++++++++++ LogarithmPlotter/i18n/lp_fr.ts | 13 +++++++++++ LogarithmPlotter/i18n/lp_hu.ts | 13 +++++++++++ LogarithmPlotter/i18n/lp_nb_NO.ts | 13 +++++++++++ LogarithmPlotter/i18n/lp_template.ts | 13 +++++++++++ .../LogarithmPlotter/LogGraphCanvas.qml | 22 +++++++++++++++++-- .../ObjectLists/Editor/CustomPropertyList.qml | 2 +- 9 files changed, 112 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 86dccae..c762813 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -1046,6 +1046,14 @@ Evaluated expression: %3 Ausdruck analysiert: %3 + + + Error while attempting to draw %1 %2: +%3 + +Undoing last change. + + expression @@ -1066,6 +1074,11 @@ Evaluated expression: %3 Ausdruck analysiert: %3 + + + LogarithmPlotter - Drawing error + + function diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 711f2cc..2a43526 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -1046,6 +1046,14 @@ Evaluated expression: %3 Evaluated expression: %3 + + + Error while attempting to draw %1 %2: +%3 + +Undoing last change. + + expression @@ -1066,6 +1074,11 @@ Evaluated expression: %3 Evaluated expression: %3 + + + LogarithmPlotter - Drawing error + + function diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index a6ccaec..307c1fa 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -991,6 +991,14 @@ These settings can be changed at any time from the "Settings" menu. + + + Error while attempting to draw %1 %2: +%3 + +Undoing last change. + + expression @@ -1008,6 +1016,11 @@ Evaluated expression: %3 Evaluated expression: %3 + + + LogarithmPlotter - Drawing error + + function diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 70fd443..ef59464 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -1055,6 +1055,14 @@ Evaluated expression: %3 Formule analysée : %3 + + + Error while attempting to draw %1 %2: +%3 + +Undoing last change. + + expression @@ -1075,6 +1083,11 @@ Evaluated expression: %3 Formule analysée : %3 + + + LogarithmPlotter - Drawing error + + function diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 355b65a..46fd264 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1046,6 +1046,14 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 + + + Error while attempting to draw %1 %2: +%3 + +Undoing last change. + + expression @@ -1066,6 +1074,11 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 + + + LogarithmPlotter - Drawing error + + function diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 1181e93..6daa1a1 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -1043,6 +1043,14 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + + + Error while attempting to draw %1 %2: +%3 + +Undoing last change. + + expression @@ -1060,6 +1068,11 @@ Evaluated expression: %3 Evaluated expression: %3 + + + LogarithmPlotter - Drawing error + + function diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index ffda6b0..8390e18 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -991,6 +991,14 @@ These settings can be changed at any time from the "Settings" menu. + + + Error while attempting to draw %1 %2: +%3 + +Undoing last change. + + expression @@ -1008,6 +1016,11 @@ Evaluated expression: %3 Evaluated expression: %3 + + + LogarithmPlotter - Drawing error + + function diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 7ab2153..bd10c29 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -16,7 +16,8 @@ * along with this program. If not, see . */ -import QtQuick +import QtQuick +import Qt.labs.platform as Native import "js/objects.js" as Objects import "js/utils.js" as Utils import "js/mathlib.js" as MathLib @@ -170,6 +171,16 @@ Canvas { Component.onCompleted: imageLoaders = {} + Native.MessageDialog { + id: drawingErrorDialog + title: qsTranslate("expression", "LogarithmPlotter - Drawing error") + text: "" + function showDialog(objType, objName, error) { + text = qsTranslate("error", "Error while attempting to draw %1 %2:\n%3\n\nUndoing last change.").arg(objType).arg(objName).arg(error) + open() + } + } + onPaint: function(rect) { //console.log('Redrawing') if(rect.width == canvas.width) { // Redraw full canvas @@ -183,7 +194,14 @@ Canvas { for(var obj of Objects.currentObjects[objType]){ ctx.strokeStyle = obj.color ctx.fillStyle = obj.color - if(obj.visible) obj.draw(canvas, ctx) + if(obj.visible) + try { + obj.draw(canvas, ctx) + } catch(e) { + // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) + drawingErrorDialog.showDialog(objType, obj.name, e.message) + history.undo() + } } } ctx.lineWidth = 1 diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 0551d2e..a800c6e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -91,7 +91,7 @@ Repeater { root.changed() } } - } + } } From 9239eac78a52208dfd6ef7409610c47a7db77df3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 07:43:40 +0200 Subject: [PATCH 117/436] Fixing several function calls with no argument errors. + Functions max and min now throw an error if no arguments are provided. + Objects called now throw an error if no argument is provided. + Fixing tokenizer's seek error reporting system (leads to very rare types of errors). + Removing expression simplifications that could make the app freeze when no arguments are provided to a function. --- .../ad5001/LogarithmPlotter/js/expr-eval.js | 13 ++++++++--- .../LogarithmPlotter/js/parsing/common.js | 2 +- .../eu/ad5001/LogarithmPlotter/js/utils.js | 22 +++++++++---------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 0df2661..6417e83 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -241,7 +241,10 @@ function evaluate(tokens, expr, values) { nstack.push(f.apply(undefined, args)); } else if(f.execute) { // Objects & expressions execution - nstack.push(f.execute.apply(f, args)); + if(args.length >= 1) + nstack.push(f.execute.apply(f, args)); + else + throw new Error(qsTranslate('error', 'In order to be executed, object %1 must have at least one argument.').arg(f)) } else { throw new Error(qsTranslate('error', '%1 cannot be executed.').arg(f)); } @@ -1614,16 +1617,20 @@ function arrayIndex(array, index) { function max(array) { if (arguments.length === 1 && Array.isArray(array)) { return Math.max.apply(Math, array); - } else { + } else if(arguments.length >= 1) { return Math.max.apply(Math, arguments); + } else { + throw new EvalError(qsTranslate('error', 'Function %1 must have at least one argument.').arg('max')) } } function min(array) { if (arguments.length === 1 && Array.isArray(array)) { return Math.min.apply(Math, array); - } else { + } else if(arguments.length >= 1) { return Math.min.apply(Math, arguments); + } else { + throw new EvalError(qsTranslate('error', 'Function %1 must have at least one argument.').arg('min')) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js index 4e7f6fe..dab0969 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js @@ -36,7 +36,7 @@ class InputExpression { if(!this.atEnd() && this.peek() == char) { this.position++; } else { - this.raise("Unexpected character " + peek() + ". Expected character " + char); + this.raise("Unexpected character " + this.peek() + ". Expected character " + char); } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index ee53afa..9121661 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -216,16 +216,16 @@ function simplifyExpression(str) { } ], // Simple simplifications - [/(\s|^|\()0(\.0+)? \* (\([^)(]+\))/g, '$10'], - [/(\s|^|\()0(\.0+)? \* ([^)(+-]+)/g, '$10'], - [/(\([^)(]\)) \* 0(\.0+)?(\s|$|\))/g, '0$3'], - [/([^)(+-]) \* 0(\.0+)?(\s|$|\))/g, '0$3'], - [/(\s|^|\()1(\.0+)? (\*|\/) /g, '$1'], - [/(\s|^|\()0(\.0+)? (\+|\-) /g, '$1'], - [/ (\*|\/) 1(\.0+)?(\s|$|\))/g, '$3'], - [/ (\+|\-) 0(\.0+)?(\s|$|\))/g, '$3'], - [/(^| |\() /g, '$1'], - [/ ($|\))/g, '$1'], + // [/(\s|^|\()0(\.0+)? \* (\([^)(]+\))/g, '$10'], + // [/(\s|^|\()0(\.0+)? \* ([^)(+-]+)/g, '$10'], + // [/(\([^)(]\)) \* 0(\.0+)?(\s|$|\))/g, '0$3'], + // [/([^)(+-]) \* 0(\.0+)?(\s|$|\))/g, '0$3'], + // [/(\s|^|\()1(\.0+)? (\*|\/) /g, '$1'], + // [/(\s|^|\()0(\.0+)? (\+|\-) /g, '$1'], + // [/ (\*|\/) 1(\.0+)?(\s|$|\))/g, '$3'], + // [/ (\+|\-) 0(\.0+)?(\s|$|\))/g, '$3'], + // [/(^| |\() /g, '$1'], + // [/ ($|\))/g, '$1'], ] // Replacements @@ -271,7 +271,7 @@ function makeExpressionReadable(str) { }] ] - str = simplifyExpression(str) + // str = simplifyExpression(str) // Replacements for(var replacement of replacements) while(replacement[0].test(str)) From 40743e54c37b32c0f994f33b0251627a058f32ea Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 08:00:58 +0200 Subject: [PATCH 118/436] Allow the user to choose what he wants to pick. Updating translations. --- LogarithmPlotter/i18n/lp_de.ts | 94 ++++++++++++------- LogarithmPlotter/i18n/lp_en.ts | 94 ++++++++++++------- LogarithmPlotter/i18n/lp_es.ts | 90 +++++++++++------- LogarithmPlotter/i18n/lp_fr.ts | 94 ++++++++++++------- LogarithmPlotter/i18n/lp_hu.ts | 94 ++++++++++++------- LogarithmPlotter/i18n/lp_nb_NO.ts | 94 ++++++++++++------- LogarithmPlotter/i18n/lp_template.ts | 90 +++++++++++------- .../LogarithmPlotter/PickLocationOverlay.qml | 64 +++++++++---- 8 files changed, 474 insertions(+), 240 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index c762813..c50b71b 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -569,25 +569,44 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" PickLocationOverlay - + Pointer precision: Genauigkeit des Zeigers: - Snap to grid - Am Gitter einrasten + Am Gitter einrasten - + + Snap to grid: + + + + + Pick X + + + + + Pick Y + + + + Open picker settings Zeigereinstellungen öffnen - + Hide picker settings Zeigereinstellungen ausblenden + + + (no pick selected) + + Settings @@ -877,7 +896,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. @@ -887,126 +906,137 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Die Variable %1 ist nicht definiert. - + + In order to be executed, object %1 must have at least one argument. + + + + %1 cannot be executed. %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). - + Unknown character "%1". Unbekanntes Schriftzeichen "%1". - - + + Illegal escape sequence: %1. Unzulässige Escapesequenz: %1. - - + + Parse error [%1:%2]: %3 Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 - + Function definition is not permitted. Funktionsdefinition ist nicht erlaubt. - + Expected variable for assignment. Erwartete Variable für Zuweisung. - + Unexpected ".": member access is not permitted Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt - + Unexpected "[]": arrays are disabled. Unerwartetes "[]": Arrays sind deaktiviert. - + Unexpected symbol: %1. Unerwartetes Symbol: %1. - + + + Function %1 must have at least one argument. + + + + First argument to map is not a function. Der erste Parameter von map ist keine Formel. - + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 2a43526..bcd31f4 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -569,25 +569,44 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: Pointer precision: - Snap to grid - Snap to grid + Snap to grid - + + Snap to grid: + + + + + Pick X + + + + + Pick Y + + + + Open picker settings Open picker settings - + Hide picker settings Hide picker settings + + + (no pick selected) + + Settings @@ -877,7 +896,7 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. Cannot find property %1 of object %2. @@ -887,126 +906,137 @@ These settings can be changed at any time from the "Settings" menu.Undefined variable %1. - + + In order to be executed, object %1 must have at least one argument. + + + + %1 cannot be executed. %1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). - + Unknown character "%1". Unknown character "%1". - - + + Illegal escape sequence: %1. Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 Parse error [%1:%2]: %3 - + Expected %1 Expected %1 - + Unexpected %1 Unexpected %1 - + Function definition is not permitted. Function definition is not permitted. - + Expected variable for assignment. Expected variable for assignment. - + Unexpected ".": member access is not permitted Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. Unexpected symbol: %1. - + + + Function %1 must have at least one argument. + + + + First argument to map is not a function. First argument to map is not a function. - + Second argument to map is not an array. Second argument to map is not an array. - + First argument to fold is not a function. First argument to fold is not a function. - + Second argument to fold is not an array. Second argument to fold is not an array. - + First argument to filter is not a function. First argument to filter is not a function. - + Second argument to filter is not an array. Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - + Second argument to join is not an array. Second argument to join is not an array. - + EOF End of expression diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 307c1fa..8f4f452 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -517,25 +517,40 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - - Snap to grid + + Snap to grid: - + + Pick X + + + + + Pick Y + + + + Open picker settings - + Hide picker settings + + + (no pick selected) + + Settings @@ -825,7 +840,7 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. @@ -835,126 +850,137 @@ These settings can be changed at any time from the "Settings" menu. - + + In order to be executed, object %1 must have at least one argument. + + + + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + + + Function %1 must have at least one argument. + + + + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index ef59464..ccfa587 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -577,25 +577,44 @@ These settings can always be changed at any time from the "Settings" m PickLocationOverlay - + Pointer precision: Précision du pointeur : - Snap to grid - Placement sur la grille + Placement sur la grille - + + Snap to grid: + + + + + Pick X + + + + + Pick Y + + + + Open picker settings Ouvrir les paramètres du pointeur - + Hide picker settings Cacher les paramètres du pointeur + + + (no pick selected) + + Settings @@ -886,7 +905,7 @@ These settings can always be changed at any time from the "Settings" m error - + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. @@ -896,126 +915,137 @@ These settings can always be changed at any time from the "Settings" m La variable %1 n'est pas définie. - + + In order to be executed, object %1 must have at least one argument. + + + + %1 cannot be executed. %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). - + Unknown character "%1". Le caractère "%1" est inconnu. - - + + Illegal escape sequence: %1. Séquence d'échappement illégale : %1. - - + + Parse error [%1:%2]: %3 Erreur de syntaxe [%1:%2] : %3 - + Expected %1 %1 attendu - + Unexpected %1 %1 inattendu - + Function definition is not permitted. La définition de fonctions n'est pas autorisée. - + Expected variable for assignment. Une variable est attendue pour l'affectation. - + Unexpected ".": member access is not permitted "." inattendu : l'accès aux propriétés n'est pas autorisé - + Unexpected "[]": arrays are disabled. "[]" inattendu : les tableaux sont désactivés. - + Unexpected symbol: %1. Symbole inconnu : %1. - + + + Function %1 must have at least one argument. + + + + First argument to map is not a function. Le premier argument de map n'est pas une fonction. - + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 46fd264..feafc52 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -569,25 +569,44 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. PickLocationOverlay - + Pointer precision: Mutató pontossága: - Snap to grid - Rácshoz illesztés + Rácshoz illesztés - + + Snap to grid: + + + + + Pick X + + + + + Pick Y + + + + Open picker settings - + Hide picker settings + + + (no pick selected) + + Settings @@ -877,7 +896,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - + Cannot find property %1 of object %2. A(z) %2 objektum %1 tulajdonsága nem található. @@ -887,126 +906,137 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A(z) %1 változó nincs meghatározva. - + + In order to be executed, object %1 must have at least one argument. + + + + %1 cannot be executed. A(z) %1 nem függvény. - - - + + + Invalid expression. Érvénytelen kifejezés. - + Invalid expression (parity). Érvénytelen kifejezés (paritás). - + Unknown character "%1". Ismeretlen karakter „%1”. - - + + Illegal escape sequence: %1. Érvénytelen kilépési sorozat: %1. - - + + Parse error [%1:%2]: %3 Elemzési hiba [%1:%2]: %3 - + Expected %1 Várható %1 - + Unexpected %1 Váratlan %1 - + Function definition is not permitted. A függvény meghatározása nem engedélyezett. - + Expected variable for assignment. A hozzárendeléshez várt változó. - + Unexpected ".": member access is not permitted Váratlan „.”: a tagok hozzáférése nem engedélyezett - + Unexpected "[]": arrays are disabled. Váratlan „[]”: a tömbök le vannak tiltva. - + Unexpected symbol: %1. Váratlan szimbólum: %1. - + + + Function %1 must have at least one argument. + + + + First argument to map is not a function. Az első leképezési argumentum nem függvény. - + Second argument to map is not an array. A második leképezési argumentum nem tömb. - + First argument to fold is not a function. Az első behajtási argumentum nem függvény. - + Second argument to fold is not an array. A második behajtási argumentum nem tömb. - + First argument to filter is not a function. Az első szűrési argumentum nem függvény. - + Second argument to filter is not an array. A második szűrési argumentum nem tömb. - + Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. - + Second argument to join is not an array. A második csatlakozási argumentum nem tömb. - + EOF Kifejezés vége diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 6daa1a1..4d1cc28 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -569,25 +569,44 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. PickLocationOverlay - + Pointer precision: Peker-presisjon: - Snap to grid - Fest til rutenett + Fest til rutenett - + + Snap to grid: + + + + + Pick X + + + + + Pick Y + + + + Open picker settings - + Hide picker settings + + + (no pick selected) + + Settings @@ -877,7 +896,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.error - + Cannot find property %1 of object %2. @@ -887,126 +906,137 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + + In order to be executed, object %1 must have at least one argument. + + + + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + + + Function %1 must have at least one argument. + + + + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 8390e18..87973c3 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -517,25 +517,40 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - - Snap to grid + + Snap to grid: - + + Pick X + + + + + Pick Y + + + + Open picker settings - + Hide picker settings + + + (no pick selected) + + Settings @@ -825,7 +840,7 @@ These settings can be changed at any time from the "Settings" menu.error - + Cannot find property %1 of object %2. @@ -835,126 +850,137 @@ These settings can be changed at any time from the "Settings" menu. - + + In order to be executed, object %1 must have at least one argument. + + + + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Function definition is not permitted. - + Expected variable for assignment. - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + + + Function %1 must have at least one argument. + + + + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 5173a24..f3077b6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -56,12 +56,12 @@ Item { property string objName: 'A' /*! \qmlproperty bool PickLocationOverlay::pickX - true if the user should be picking a position on the x axis. + true if the property in propertyX is pickable. */ property bool pickX: true /*! \qmlproperty bool PickLocationOverlay::pickY - true if the user should be picking a position on the y axis. + true if the property in propertyY is pickable. */ property bool pickY: true /*! @@ -79,6 +79,16 @@ Item { Precision of the picked value (post-dot precision). */ property alias precision: precisionSlider.value + /*! + \qmlproperty bool PickLocationOverlay::userPickX + true if the user can and wants to be picking a position on the x axis. + */ + readonly property bool userPickX: pickX && pickXCheckbox.checked + /*! + \qmlproperty bool PickLocationOverlay::userPickY + true if the user can and wants to be picking a position on the y axis. + */ + readonly property bool userPickY: pickY && pickYCheckbox.checked Rectangle { color: sysPalette.window @@ -94,29 +104,33 @@ Item { acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: function(mouse) { if(mouse.button == Qt.LeftButton) { // Validate - let newValueX = !parent.pickX ? null : parseValue(picked.mouseX.toString(), objType, propertyX) - let newValueY = !parent.pickY ? null : parseValue(picked.mouseY.toString(), objType, propertyY) + let newValueX = !parent.userPickX ? null : parseValue(picked.mouseX.toString(), objType, propertyX) + let newValueY = !parent.userPickY ? null : parseValue(picked.mouseY.toString(), objType, propertyY) let obj = Objects.currentObjectsByName[objName] // Set values - if(parent.pickX && parent.pickY) { + if(parent.userPickX && parent.userPickY) { history.addToHistory(new HistoryLib.EditedPosition( objName, objType, obj[propertyX], newValueX, obj[propertyY], newValueY )) obj[propertyX] = newValueX obj[propertyY] = newValueY - } else if(parent.pickX) { + obj.update() + objectLists.update() + } else if(parent.userPickX) { history.addToHistory(new HistoryLib.EditedProperty( objName, objType, propertyX, obj[propertyX], newValueX )) obj[propertyX] = newValueX - } else if(parent.pickY) { + obj.update() + objectLists.update() + } else if(parent.userPickY) { history.addToHistory(new HistoryLib.EditedProperty( objName, objType, propertyY, obj[propertyY], newValueY )) obj[propertyY] = newValueY + obj.update() + objectLists.update() } - obj.update() - objectLists.update() } pickerRoot.visible = false; } @@ -158,11 +172,19 @@ Item { } Text { - text: qsTr("Snap to grid") + ":" + text: qsTr("Snap to grid:") color: sysPalette.windowText verticalAlignment: Text.AlignVCenter height: pickerSettingsColumn.cellHeight } + + CheckBox { + id: pickXCheckbox + height: pickerSettingsColumn.cellHeight + text: qsTr("Pick X") + checked: pickX + visible: pickX + } } Column { @@ -189,6 +211,14 @@ Item { // text: qsTr("Snap to grid") checked: false } + + CheckBox { + id: pickYCheckbox + height: pickerSettingsColumn.cellHeight + text: qsTr("Pick Y") + checked: pickY + visible: pickY + } } Button { @@ -223,7 +253,7 @@ Item { anchors.top: parent.top anchors.left: parent.left anchors.leftMargin: canvas.x2px(picked.mouseX) - visible: parent.pickX + visible: parent.userPickX } Rectangle { @@ -234,13 +264,14 @@ Item { anchors.top: parent.top anchors.left: parent.left anchors.topMargin: canvas.y2px(picked.mouseY) - visible: parent.pickY + visible: parent.userPickY } Text { id: picked x: picker.mouseX - width - 5 y: picker.mouseY - height - 5 + color: 'black' property double axisX: canvas.xaxisstep1 property double mouseX: { let xpos = canvas.px2x(picker.mouseX) @@ -264,14 +295,15 @@ Item { return ypos.toFixed(parent.precision) } } - color: 'black' text: { - if(parent.pickX && parent.pickY) + if(parent.userPickX && parent.userPickY) return `(${mouseX}, ${mouseY})` - if(parent.pickX) + else if(parent.userPickX) return `X = ${mouseX}` - if(parent.pickY) + else if(parent.userPickY) return `Y = ${mouseY}` + else + return qsTr('(no pick selected)') } } From 09c1a44150f4a736932d78b9ebdc87a50fee461a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 09:58:58 +0200 Subject: [PATCH 119/436] Adding escape shortcut for base dialog. --- .../qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml index 05de55c..be69067 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml @@ -28,6 +28,7 @@ import QtQuick.Controls */ Window { + id: base color: sysPalette.window visible: false; flags: Qt.Dialog | Qt.Popup | Qt.MSWindowsFixedSizeDialogHint @@ -35,7 +36,6 @@ Window { minimumWidth: width maximumWidth: width height: minimumHeight - // maximumHeight: contentItem.implicitHeight + 2*margin property int margin: 10 Button { @@ -48,6 +48,11 @@ Window { onClicked: close() } + Shortcut { + sequence: "Esc" + onActivated: base.close() + } + function open() { show() } From 803670635b118f8dcde740ab9ff7e46f86a1047a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 10:00:47 +0200 Subject: [PATCH 120/436] Forgot to disable Greet Screen seen saving. --- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index b3aa12b..2311821 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -228,7 +228,7 @@ Popup { } } - Component.onCompleted: if(Helper.getSetting("last_install_greet") +1 != Helper.getVersion()) { + Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()) { greetingPopup.open() } From a610d0949e7234c8945d818f0fadf136cf1f1eca Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 06:02:44 +0000 Subject: [PATCH 121/436] Translated using Weblate (English) Currently translated at 100.0% (267 of 267 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index bcd31f4..d472569 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -210,7 +210,7 @@ Pick on graph - + Pick on graph @@ -580,17 +580,17 @@ These settings can be changed at any time from the "Settings" menu. Snap to grid: - + Snap to grid: Pick X - + Pick X Pick Y - + Pick Y @@ -605,7 +605,7 @@ These settings can be changed at any time from the "Settings" menu. (no pick selected) - + (no pick selected) @@ -908,7 +908,7 @@ These settings can be changed at any time from the "Settings" menu. In order to be executed, object %1 must have at least one argument. - + In order to be executed, object %1 must have at least one argument. @@ -983,7 +983,7 @@ These settings can be changed at any time from the "Settings" menu. Function %1 must have at least one argument. - + Function %1 must have at least one argument. @@ -1071,7 +1071,7 @@ These settings can be changed at any time from the "Settings" menu. - Error while parsing expression for property %1: + Error while parsing expression for property %1: %2 Evaluated expression: %3 @@ -1082,7 +1082,10 @@ Evaluated expression: %3 %3 Undoing last change. - + Error while attempting to draw %1 %2: +%3 + +Undoing last change. @@ -1107,7 +1110,7 @@ Evaluated expression: %3 LogarithmPlotter - Drawing error - + LogarithmPlotter - Drawing error From 87b4787a2bb10bd080ac310bb30a8e8dd6ef8db9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 08:03:26 +0000 Subject: [PATCH 122/436] Translated using Weblate (German) Currently translated at 100.0% (267 of 267 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index c50b71b..c72a28e 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -210,7 +210,7 @@ Pick on graph - + Aufnehmen auf Graph @@ -580,17 +580,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Snap to grid: - + Am Raster einrasten: Pick X - + X nehmen Pick Y - + Y nehmen @@ -605,7 +605,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" (no pick selected) - + (keine Auswahl ausgewählt) @@ -908,7 +908,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" In order to be executed, object %1 must have at least one argument. - + Um als Funktion verwendet zu werden, benötigt das Objekt %1 mindestens ein Parameter. @@ -983,7 +983,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Function %1 must have at least one argument. - + Die Funktion %1 benötigt mindestens ein Parameter. @@ -1071,7 +1071,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" %2 Evaluated expression: %3 - Fehler beim Analysieren des Ausdrucks für die Eigenschaft %1: + Fehler beim Analysieren des Ausdrucks für die Eigenschaft %1: %2 Ausdruck analysiert: %3 @@ -1082,7 +1082,10 @@ Ausdruck analysiert: %3 %3 Undoing last change. - + Fehler beim Versuch, das %1 %2 zu zeichnen: +%3 + +Die letzte Änderung wurde rückgängig gemacht. @@ -1107,7 +1110,7 @@ Ausdruck analysiert: %3 LogarithmPlotter - Drawing error - + LogarithmPlotter - Fehler From 98f01845e186fa342552e6775fd49b0c18298d69 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 06:05:12 +0000 Subject: [PATCH 123/436] Translated using Weblate (French) Currently translated at 100.0% (267 of 267 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index ccfa587..e6aea4b 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -211,7 +211,7 @@ Pick on graph - + Prendre la position sur le graphe @@ -588,17 +588,17 @@ These settings can always be changed at any time from the "Settings" m Snap to grid: - + Aligner sur la grille : Pick X - + Prendre la position X Pick Y - + Prendre la position Y @@ -613,7 +613,7 @@ These settings can always be changed at any time from the "Settings" m (no pick selected) - + (aucun axe sélectionné) @@ -917,7 +917,7 @@ These settings can always be changed at any time from the "Settings" m In order to be executed, object %1 must have at least one argument. - + Pour être utilisé comme fonction, l'objet %1 nécessite au moins un argument. @@ -992,7 +992,7 @@ These settings can always be changed at any time from the "Settings" m Function %1 must have at least one argument. - + La fonction %1 nécessite au moins un argument. @@ -1080,7 +1080,7 @@ These settings can always be changed at any time from the "Settings" m %2 Evaluated expression: %3 - Erreur lors de l'analyse de la formule pour la propriété %1 : + Erreur lors de l'analyse de la formule pour la propriété %1 : %2 Formule analysée : %3 @@ -1091,7 +1091,10 @@ Formule analysée : %3 %3 Undoing last change. - + Erreur lors de la tentative de dessin du %1 %2 : +%3 + +La dernière modification a été annulée. @@ -1116,7 +1119,7 @@ Formule analysée : %3 LogarithmPlotter - Drawing error - + LogarithmPlotter - Erreur From 16effe064ccea1be195ce7812ad2e7a2defd29f9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 24 May 2023 11:49:45 +0200 Subject: [PATCH 124/436] Disabling generation of HDPI latex pngs, as they aren't used in PySide6. --- LogarithmPlotter/util/latex.py | 6 +++--- setup.py | 5 +---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index d5e362e..3690f83 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -98,9 +98,9 @@ class Latex(QObject): self.cleanup(latex_path) # Creating four pictures of different sizes to better handle dpi. self.convert_dvi_to_png(latex_path, export_path, font_size, color) - self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) - self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) - self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) + # self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) + # self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) + # self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) except Exception as e: # One of the processes failed. A message will be sent every time. raise e img = QImage(export_path); diff --git a/setup.py b/setup.py index cb3d90a..dd59380 100644 --- a/setup.py +++ b/setup.py @@ -25,6 +25,7 @@ print(sys.argv) current_dir = os.path.realpath(os.path.dirname(os.path.realpath(__file__))) +# Check where to install by default if "PREFIX" not in os.environ and sys.platform == 'linux': from getopt import getopt optlist, args = getopt(sys.argv, '', ['prefix=', 'root=']) @@ -100,8 +101,6 @@ if sys.platform == 'linux': data_files.append((os.environ["PREFIX"] + '/mime/packages/', ['linux/x-logarithm-plot.xml'])) data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/', ['linux/application-x-logarithm-plot.svg'])) data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['logplotter.svg'])) - if "FLATPAK_INSTALL" not in os.environ: - data_files.append((os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/', ['logplotter.svg'])) if len(sys.argv) > 1: if sys.argv[1] == "install": os.makedirs(os.environ["PREFIX"] + '/applications/', exist_ok=True) @@ -113,8 +112,6 @@ if sys.platform == 'linux': copyfile(current_dir + '/linux/application-x-logarithm-plot.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/mimetypes/application-x-logarithm-plot.svg') copyfile(current_dir + '/logplotter.svg', os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') - #copyfile(current_dir + '/linux/eu.ad5001.LogarithmPlotter.metainfo.xml', os.environ["PREFIX"] + '/metainfo/eu.ad5001.LogarithmPlotter.metainfo.xml') - #copyfile(current_dir + '/linux/logarithmplotter.desktop', os.environ["PREFIX"] + '/applications/logarithmplotter.desktop') elif sys.argv[1] == "uninstall": os.remove(os.environ["PREFIX"] + '/applications/logarithmplotter.desktop') os.remove(os.environ["PREFIX"] + '/mime/packages/x-logarithm-plot.xml') From 6fa0aea0e5204f12f1ae294012098356c13dade3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 25 May 2023 10:27:27 +0200 Subject: [PATCH 125/436] Disabling auto detect of qtquick style if manual set. --- LogarithmPlotter/logarithmplotter.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 7e1c2af..f0beba2 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -65,13 +65,14 @@ def get_linux_theme(): def run(): - environ["QT_QUICK_CONTROLS_STYLE"] = { - "linux": get_linux_theme(), - "freebsd": get_linux_theme(), - "win32": "universal" if os_release == "10" else "fusion", - "cygwin": "fusion", - "darwin": "default" - }[platform] + if not 'QT_QUICK_CONTROLS_STYLE' in environ: + environ["QT_QUICK_CONTROLS_STYLE"] = { + "linux": get_linux_theme(), + "freebsd": get_linux_theme(), + "win32": "universal" if os_release == "10" else "fusion", + "cygwin": "fusion", + "darwin": "default" + }[platform] dep_time = time() print("Loaded dependencies in " + str((dep_time - start_time)*1000) + "ms.") From 62e70885e08608089a8463eedd842a4da3a493ed Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 25 May 2023 12:15:35 +0200 Subject: [PATCH 126/436] Changing default themes for the ones available in Qt6 --- LogarithmPlotter/logarithmplotter.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index f0beba2..e270bac 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -52,13 +52,13 @@ config.init() def get_linux_theme(): des = { - "KDE": "default", - "gnome": "default", - "lxqt": "fusion", - "mate": "fusion", + "KDE": "Fusion", + "gnome": "Basic", + "lxqt": "Fusion", + "mate": "Fusion", } if "XDG_SESSION_DESKTOP" in environ: - return des[environ["XDG_SESSION_DESKTOP"]] if environ["XDG_SESSION_DESKTOP"] in des else "fusion" + return des[environ["XDG_SESSION_DESKTOP"]] if environ["XDG_SESSION_DESKTOP"] in des else "Fusion" else: # Android return "Material" @@ -69,9 +69,9 @@ def run(): environ["QT_QUICK_CONTROLS_STYLE"] = { "linux": get_linux_theme(), "freebsd": get_linux_theme(), - "win32": "universal" if os_release == "10" else "fusion", - "cygwin": "fusion", - "darwin": "default" + "win32": "Universal" if os_release == "10" else "Fusion", + "cygwin": "Fusion", + "darwin": "Default" }[platform] dep_time = time() From 8358cc142ccd41d01c380b8f1b34a00fc5eda52a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 25 May 2023 15:08:12 +0200 Subject: [PATCH 127/436] Fixing localisation issue on position picker --- .../qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index f3077b6..e26da61 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -162,7 +162,7 @@ Item { Column { spacing: 5 - width: 100 + // width: 100 Text { text: qsTr("Pointer precision:") From deb4355756fbe2383cb06782dda87d8a077ffb9d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 25 May 2023 19:40:06 +0200 Subject: [PATCH 128/436] Preparing debian package for PySide6 --- linux/debian/control | 2 +- linux/debian/depends | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/debian/control b/linux/debian/control index 82b3fcd..db89220 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -3,7 +3,7 @@ Source: logarithmplotter Version: 0.4.0 Architecture: all Maintainer: Ad5001 -Depends: python3, python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), texlive-latex-base, dvipng +Depends: python3, python3-pip, python3-pyside6-essentials (>= 6.4.0), texlive-latex-base, dvipng Build-Depends: debhelper (>=11~), dh-python, dpkg-dev (>= 1.16.1~), python-setuptools, python3-all-dev (>=3.6) Section: science diff --git a/linux/debian/depends b/linux/debian/depends index 53dcda3..fb79d69 100644 --- a/linux/debian/depends +++ b/linux/debian/depends @@ -1 +1 @@ -python3-pip, qml-module-qtquick-controls2 (>= 5.12.0), qml-module-qtmultimedia (>= 5.12.0), qml-module-qtgraphicaleffects (>= 5.12.0), qml-module-qtquick2 (>= 5.12.0), qml-module-qtqml-models2 (>= 5.12.0), qml-module-qtquick-controls (>= 5.12.0), python3-pyside2.qtcore (>= 5.12.0), python3-pyside2.qtqml (>= 5.12.0), python3-pyside2.qtgui (>= 5.12.0), python3-pyside2.qtquick (>= 5.12.0), python3-pyside2.qtwidgets (>= 5.12.0), python3-pyside2.qtmultimedia (>= 5.12.0), python3-pyside2.qtnetwork (>= 5.12.0), texlive-latex-base, dvipng +python3, python3-pip, python3-pyside6-essentials (>= 6.4.0), texlive-latex-base, dvipng From 66da751b3662f85ef812c9f97c1918110356836b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 26 May 2023 06:25:29 +0200 Subject: [PATCH 129/436] Updating windows builders for pyside6 (halving the bundled installer size) --- scripts/build-windows.bat | 12 ++++++++++-- scripts/build-wine.sh | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/scripts/build-windows.bat b/scripts/build-windows.bat index a29d291..ef92aee 100644 --- a/scripts/build-windows.bat +++ b/scripts/build-windows.bat @@ -1,5 +1,5 @@ -rem Need pyinstaller >= 4.3, or there is an issue regarding the PATH of the building. -python -m pip install -U pyinstaller>=4.3 +rem Make sure pyinstaller is installed +python -m pip install -U pyinstaller rem Building translations cd "LogarithmPlotter\i18n" @@ -7,3 +7,11 @@ cmd release.sh cd ..\.. pyinstaller --add-data "logplotter.svg;." --add-data "LogarithmPlotter/qml;qml" --add-data "LogarithmPlotter/i18n;i18n" --noconsole LogarithmPlotter/logarithmplotter.py --icon=win/logarithmplotter.ico -n logarithmplotter + +rem Remove QtWebEngine +del dist\logarithmplotter\PySide6\Qt6WebEngineCore.dll +rem Remove the QtQuick styles that are unused +rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\Imagine /s /q +rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\Material /s /q +rmdir dist\logarithmplotter\PySide6\qml\QtQuick\Controls\designer /s /q +rem Remove unused translations diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index 3406bbc..7ff3394 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -1,7 +1,8 @@ #!/bin/bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -# Giving pyinstaller another run +rm -rf dist + rm $(find . -name "*.qmlc") rm -rf $(find . -name "*.pyc") wine python -m pip install -U pyinstaller @@ -12,3 +13,18 @@ bash release.sh cd ../../ wine pyinstaller --add-data "logplotter.svg;." --add-data "LogarithmPlotter/qml;qml" --add-data "LogarithmPlotter/i18n;i18n" --noconsole LogarithmPlotter/logarithmplotter.py --icon=win/logarithmplotter.ico -n logarithmplotter + +# Copy Qt6ShaderTools, a required library for for Qt5Compat +PYSIDE6PATH="$(wine python -c "import PySide6; from os import path; print(path.dirname(PySide6.__file__));")" +# Converting PySide6 path to absolute path +DRIVEC="${WINEPREFIX:-$HOME/.wine}/drive_c" +PYSIDE6PATH="${PYSIDE6PATH%$'\r'}" +PYSIDE6PATH="${PYSIDE6PATH//\\/\/}" +PYSIDE6PATH="${PYSIDE6PATH//C:/$DRIVEC}" +cp "$PYSIDE6PATH/Qt6ShaderTools.dll" dist/logarithmplotter/PySide6/ + +# Remove QtWebEngine +rm dist/logarithmplotter/PySide6/Qt6WebEngineCore.dll + +# Remove the QtQuick styles that are unused +rm -rf dist/logarithmplotter/PySide6/qml/QtQuick/Controls/{Imagine,Material,designer} From 59145905ea7ff33ae94cff0b6a33100e357cf2f6 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 26 May 2023 08:16:48 +0200 Subject: [PATCH 130/436] Changing dependencies to only PySide6's essentials. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index dd59380..8e78439 100644 --- a/setup.py +++ b/setup.py @@ -119,7 +119,7 @@ if sys.platform == 'linux': os.remove(os.environ["PREFIX"] + '/icons/hicolor/scalable/apps/logplotter.svg') setuptools.setup( - install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6"]), + install_requires=([] if "FLATPAK_INSTALL" in os.environ else ["PySide6-Essentials"]), python_requires='>=3.8', name='logarithmplotter', From 95546bd14e93763cff83bdbad8147cc9a4b09783 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 26 May 2023 14:54:28 +0200 Subject: [PATCH 131/436] Qt6 testing and porting on macOS. --- LogarithmPlotter/logarithmplotter.py | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index e270bac..3f9be9a 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -71,7 +71,7 @@ def run(): "freebsd": get_linux_theme(), "win32": "Universal" if os_release == "10" else "Fusion", "cygwin": "Fusion", - "darwin": "Default" + "darwin": "macOS" }[platform] dep_time = time() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 2311821..08e1d47 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -228,7 +228,7 @@ Popup { } } - Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()) { + Component.onCompleted: if(Helper.getSetting("last_install_greet")+1 != Helper.getVersion()) { greetingPopup.open() } From ebf07dccfa04b2f693dffa76e4643938bd6ef50f Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 26 May 2023 18:05:05 +0200 Subject: [PATCH 132/436] Disabling interactive thanks dialog. --- .../qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml index 80a0c2d..bb152e3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -53,6 +53,7 @@ BaseDialog { width: parent.width //height: parent.height implicitHeight: contentItem.childrenRect.height + interactive: false model: ListModel { Component.onCompleted: { @@ -135,6 +136,7 @@ BaseDialog { model: authors width: parent.width - 10 implicitHeight: contentItem.childrenRect.height + interactive: false delegate: Item { id: libAuthor @@ -191,6 +193,7 @@ BaseDialog { anchors.left: parent.left width: parent.width implicitHeight: contentItem.childrenRect.height + interactive: false spacing: 3 @@ -292,6 +295,7 @@ BaseDialog { model: authors width: parent.width - 10 implicitHeight: contentItem.childrenRect.height + interactive: false delegate: Item { id: tranAuthor From 1e30bee22093b3b4e1b608fde73fbec6c02a4d6d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 26 May 2023 20:11:41 +0200 Subject: [PATCH 133/436] Updating snapcraft building --- snapcraft.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index ebc4625..7be0d43 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,6 +1,6 @@ name: logarithmplotter title: LogarithmPlotter -version: '0.3.0' +version: '0.4.0' summary: 2D logarithmic-scaled plotter software to create asymptotic Bode plots confinement: strict base: core20 @@ -129,6 +129,7 @@ parts: - libxcb-xfixes0 - libxcb-xinerama0 - libxcb-xkb1 + - libxcb-cursor0 - libxkbcommon-x11-0 - libxkbcommon0 - libxcb-render-util0 From 5e7dbb8fa6f31e3d45587deba86fab6d53e16359 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 27 May 2023 10:07:40 +0200 Subject: [PATCH 134/436] Adding changelog --- CHANGELOG.md | 35 ++++++++ linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 79 +++++++++++++++---- 2 files changed, 99 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd3b795..5c96005 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## v0.4.0 (27 May 2023) + +**Changes** + + * Fully ported to PySide6 (Qt6). + * Greet screen settings are now scrollable. + * Changelog is now freezed to current version. + +**New** + + * Customizable color schemes for expressions. + * New, rewamped and improved picked location overlay settings: + * It's now possible to disable picking x or y when setting a location. + * Properties which are related to positioning (X, Y, Label's X position) can now be set using the picker. + * Visual redesign that enhances readability of settings. + * There is now a button to hide picker settings. + +**Fixed bugs** + + * Cursors in expression are now easier to see. + * Symbols in LaTeX rendered Texts cause the LaTeX renderer to crash. + * Underscores in distribution names are automatically removed if the name is modified. + * Autocomplete categories now properly respect theme colors. + * Functions in expressions (like indexOf, map...) now properly send errors when the arguments are of the wrong type or count. + * Executable Objects called (like functions, bode magnitures, phases...) now send an error if provided with no arguments. + * Function calls with no argument no longer make LogarithmPlotter crash under certain circumstances. + * Thank you dialog's lists are no longer draggable. + +**Internal changes** + + * A lot of inner changes led by porting to Qt6, fixing a lot of bugs at the same time. + * Disabled auto detect of visual theme if the `QT_QUICK_CONTROLS_STYLE` environment variable is set. + * (macOS, Windows, Flatpak) Drastically reducing installer sizes (more than halved). + * (Launchpad/Ubuntu) Using custom built packages of PySide6, meaning smaller installation and distro dependency. + ## v0.3.0 (28 Oct 2022) **New** diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 9c8f3a8..84be4f6 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -85,21 +85,21 @@ https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/ https://hosted.weblate.org/engage/logarithmplotter/ - https://apps.ad5001.eu/img/full/logarithmplotter.png?v=0.3 - https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.3 - https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.3 - https://apps.ad5001.eu/img/de/gain.png?v=0.3 - https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.3 - https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.3 - https://apps.ad5001.eu/img/fr/gain.png?v=0.3 - https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.3 - https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.3 - https://apps.ad5001.eu/img/hu/gain.png?v=0.3 - https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.3 - https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.3 - https://apps.ad5001.eu/img/no/gain.png?v=0.3 - https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.3 - https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.3 + https://apps.ad5001.eu/img/full/logarithmplotter.png?v=0.4 + https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.4 + https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.4 + https://apps.ad5001.eu/img/de/gain.png?v=0.4 + https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.4 + https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.4 + https://apps.ad5001.eu/img/fr/gain.png?v=0.4 + https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.4 + https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.4 + https://apps.ad5001.eu/img/hu/gain.png?v=0.4 + https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.4 + https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.4 + https://apps.ad5001.eu/img/no/gain.png?v=0.4 + https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.4 + https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.4 @@ -115,6 +115,55 @@ + + +

    Changes for v0.4.0:

    +

    Changes

    +
      +
    • Fully ported to PySide6 (Qt6).
    • +
    • Greet screen settings are now scrollable.
    • +
    • Changelog is now freezed to current version.
    • +
    +

    New

    +
      +
    • Customizable color schemes for expressions.
    • +
    • New, rewamped and improved picked location overlay settings:
    • +
    • It's now possible to disable picking x or y when setting a location.
    • +
    • Properties which are related to positioning (X, Y, Label's X position) can now be set using the picker.
    • +
    • Visual redesign that enhances readability of settings.
    • +
    • There is now a button to hide picker settings.
    • +
    +

    Fixed bugs

    +
      +
    • Cursors in expression are now easier to see.
    • +
    • Symbols in LaTeX rendered Texts cause the LaTeX renderer to crash.
    • +
    • Underscores in distribution names are automatically removed if the name is modified.
    • +
    • Autocomplete categories now properly respect theme colors.
    • +
    • Functions in expressions (like indexOf, map...) now properly send errors when the arguments are of the wrong type or count.
    • +
    • Executable Objects called (like functions, bode magnitures, phases...) now send an error if provided with no arguments.
    • +
    • Function calls with no argument no longer make LogarithmPlotter crash under certain circumstances.
    • +
    • Thank you dialog's lists are no longer draggable.
    • +
    +

    Internal changes

    +
      +
    • A lot of inner changes led by porting to Qt6, fixing a lot of bugs at the same time.
    • +
    • Disabled auto detect of visual theme if the QT_QUICK_CONTROLS_STYLE environment variable is set.
    • +
    • (macOS, Windows, Flatpak) Drastically reducing installer sizes (more than halved).
    • +
    • (Launchpad/Ubuntu) Using custom built packages of PySide6, meaning smaller installation and distro dependency.
    • +
    +
    + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-v0.4.0-setup.exe + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/LogarithmPlotter-v0.4.0-setup.dmg + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-0.4.0.tar.gz + + +

    Changes for v0.3.0:

    From 273d5539ec1e25768d0a2891b2050a5a719011f9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 27 May 2023 10:11:19 +0200 Subject: [PATCH 135/436] Forgot to update the debian changelog. --- linux/debian/changelog | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/linux/debian/changelog b/linux/debian/changelog index f4e95a3..7daad8d 100644 --- a/linux/debian/changelog +++ b/linux/debian/changelog @@ -1,3 +1,32 @@ +logarithmplotter (0.3.0) stable; urgency=medium + + * Fully ported to PySide6 (Qt6). + + * New: Customizable color schemes for expressions. + * New, rewamped and improved picked location overlay settings: + * It's now possible to disable picking x or y when setting a location. + * Properties which are related to positioning (X, Y, Label's X position) can now be set using the picker. + * Visual redesign that enhances readability of settings. + * There is now a button to hide picker settings. + + * Changed: Greet screen settings are now scrollable. + * Changed: Changelog is now freezed to current version. + + * Fixed bug: Cursors in expression are now easier to see. + * Fixed bug: Symbols in LaTeX rendered Texts cause the LaTeX renderer to crash. + * Fixed bug: Underscores in distribution names are automatically removed if the name is modified. + * Fixed bug: Autocomplete categories now properly respect theme colors. + * Fixed bug: Functions in expressions (like indexOf, map...) now properly send errors when the arguments are of the wrong type or count. + * Fixed bug: Executable Objects called (like functions, bode magnitures, phases...) now send an error if provided with no arguments. + * Fixed bug: Function calls with no argument no longer make LogarithmPlotter crash under certain circumstances. + * Fixed bug: Thank you dialog's lists are no longer draggable. + + * Internal change: Disabled auto detect of visual theme if the `QT_QUICK_CONTROLS_STYLE` environment variable is set. + * Internal change: (macOS, Windows, Flatpak) Drastically reducing installer sizes (more than halved). + * Internal change: (Launchpad/Ubuntu) Using custom built packages of PySide6, meaning smaller installation and distro dependency. + + -- Ad5001 Fri, 27 May 2023 17:00:00 +0100 + logarithmplotter (0.3.0) stable; urgency=medium * New: Completely revamped expression editor: From 19e403ce9883e8debd2905e0773b0dba370bffca Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 27 May 2023 10:11:42 +0200 Subject: [PATCH 136/436] Forgot to remove auto reappearance from greet screen. --- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 08e1d47..2311821 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -228,7 +228,7 @@ Popup { } } - Component.onCompleted: if(Helper.getSetting("last_install_greet")+1 != Helper.getVersion()) { + Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()) { greetingPopup.open() } From df3e7d47965ce4f7a3f5d6dd69af12c85737adc5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 27 May 2023 10:36:37 +0200 Subject: [PATCH 137/436] I thought I pushed the updated script for macOS, but it looks like I didn't. --- scripts/build-macosx.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index c4b7686..296d088 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash -cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." +DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$DIR/.." rm $(find . -name "*.qmlc") @@ -30,3 +31,15 @@ pyinstaller --add-data "LogarithmPlotter/qml:qml" \ LogarithmPlotter/logarithmplotter.py cp mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.plist + +# Remove QtWebEngine, 3D and all other unused libs libs +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/{QtWeb*,*3D*,QtRemote*,QtPdf,QtCharts,QtLocation,QtTest,QtNetwork,QtMultimedia,QtSpatialAudio,QtDataVisualization,QtQuickParticles,QtChartsQml,QtScxml,QtDataVisualizationQml,QtTest,QtPositioningQuick,QtQuickTest,QtSql,QtSensorsQuick} +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/{QtNetwork.abi3.so} + +# Removing QtQuick3D +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtQuick3D +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/Qt3D +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtWebEngine + +# Remove the QtQuick styles that are unused +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtQuick/Controls/{Imagine,Material,iOS,Universal,Fusion,designer} From e67619771ba96ce3eee531a2685aa865968d7dbb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 27 May 2023 11:09:13 +0200 Subject: [PATCH 138/436] Fixing macOS building script. --- scripts/build-macosx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index 296d088..c528f1a 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -33,7 +33,7 @@ pyinstaller --add-data "LogarithmPlotter/qml:qml" \ cp mac/Info.plist dist/LogarithmPlotter.app/Contents/Info.plist # Remove QtWebEngine, 3D and all other unused libs libs -rm -rf dist/LogarithmPlotter.app/Contents/MacOS/{QtWeb*,*3D*,QtRemote*,QtPdf,QtCharts,QtLocation,QtTest,QtNetwork,QtMultimedia,QtSpatialAudio,QtDataVisualization,QtQuickParticles,QtChartsQml,QtScxml,QtDataVisualizationQml,QtTest,QtPositioningQuick,QtQuickTest,QtSql,QtSensorsQuick} +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/{QtWeb*,*3D*,QtRemote*,QtPdf,QtCharts,QtLocation,QtTest,QtMultimedia,QtSpatialAudio,QtDataVisualization,QtQuickParticles,QtChartsQml,QtScxml,QtDataVisualizationQml,QtTest,QtPositioningQuick,QtQuickTest,QtSql,QtSensorsQuick} rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/{QtNetwork.abi3.so} # Removing QtQuick3D @@ -42,4 +42,4 @@ rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/Qt3D rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtWebEngine # Remove the QtQuick styles that are unused -rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtQuick/Controls/{Imagine,Material,iOS,Universal,Fusion,designer} +rm -rf dist/LogarithmPlotter.app/Contents/MacOS/PySide6/Qt/qml/QtQuick/Controls/{Imagine,Material,iOS,Universal,designer} From d6d7f3a5119151dd76f693506a3034846f8ea854 Mon Sep 17 00:00:00 2001 From: ovari Date: Sat, 10 Jun 2023 03:51:10 +0000 Subject: [PATCH 139/436] Translated using Weblate (Hungarian) Currently translated at 100.0% (267 of 267 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index feafc52..c43ddc7 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -125,7 +125,7 @@ Color Scheme - + Színséma @@ -183,7 +183,7 @@ Close - + Bezárás
    @@ -210,7 +210,7 @@ Pick on graph - + Ábra kijelölése @@ -385,7 +385,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Color scheme: - + Színséma: @@ -580,32 +580,32 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Snap to grid: - + Rácshoz igazítás: Pick X - + X kijelölése Pick Y - + Y kijelölése Open picker settings - + Kijelölési beállítások megnyitása Hide picker settings - + Kijelölési beállítások elrejtése (no pick selected) - + (nincs kijelölés kiválasztva) @@ -908,7 +908,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. In order to be executed, object %1 must have at least one argument. - + A végrehajtáshoz a(z) %1 objektumnak legalább egy argumentummal kell rendelkeznie. @@ -983,7 +983,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Function %1 must have at least one argument. - + A(z) %1 függvénynek legalább egy argumentumnak kell lennie. @@ -1071,7 +1071,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. %2 Evaluated expression: %3 - Hiba a(z) %1 tulajdonság kifejezésének elemzésekor: + Hiba a(z) %1 tulajdonság kifejezésének elemzésekor: %2 Kiértékelt kifejezés: %3 @@ -1082,7 +1082,10 @@ Kiértékelt kifejezés: %3 %3 Undoing last change. - + Hiba történt a(z) %1 %2 rajzolása közben: +%3 + +Az utolsó módosítás visszavonása. @@ -1107,7 +1110,7 @@ Kiértékelt kifejezés: %3 LogarithmPlotter - Drawing error - + LogarithmPlotter - Rajzolási hiba From 0b5aa36c2372f690245db657b0ee53642e1199f3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 7 Oct 2023 19:11:19 +0200 Subject: [PATCH 140/436] Adding view position changer overlay. --- LogarithmPlotter/logarithmplotter.py | 2 +- .../LogarithmPlotter/LogarithmPlotter.qml | 7 + .../ViewPositionChangeOverlay.qml | 131 ++++++++++++++++++ 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 3f9be9a..ea29f5f 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -144,7 +144,7 @@ def run(): if config.getSetting("check_for_updates"): check_for_updates(__VERSION__, engine.rootObjects()[0]) - exit_code = app.exec_() + exit_code = app.exec() tempdir.cleanup() config.save() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index bbc826a..4e5a68e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -178,6 +178,13 @@ ApplicationWindow { } } + ViewPositionChangeOverlay { + id: viewPositionChanger + anchors.fill: parent + canvas: parent + settingsInstance: settings + } + PickLocationOverlay { id: positionPicker anchors.fill: parent diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml new file mode 100644 index 0000000..efcf490 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -0,0 +1,131 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2023 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick +import QtQuick.Controls +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import "js/objects.js" as Objects +import "js/mathlib.js" as MathLib +import "js/historylib.js" as HistoryLib + +/*! + \qmltype ViewPositionChangeOverlay + \inqmlmodule eu.ad5001.LogarithmPlotter + \brief Overlay used allow the user to drag the canvas' position and change the zoom level. + + Provides an overlay over the canvas that detects mouse movements and changes the canvas view position + accordingly by providing new signals. + + \sa LogarithmPlotter, LogGraphCanvas, Settings +*/ +Item { + id: viewChangeRoot + visible: true + clip: true + + /*! + \qmlsignal ViewPositionChangeOverlay::positionChanged(int deltaX, int deltaY) + + Emmited when the user dragged the canvas and the view should be refreshed. + The corresponding handler is \c onPositionChanged. + */ + signal positionChanged(int deltaX, int deltaY) + + /*! + \qmlsignal ViewPositionChangeOverlay::beginPositionChange() + + Emmited when the user starts dragging the canvas. + The corresponding handler is \c onBeginPositionChange. + */ + signal beginPositionChange() + + /*! + \qmlsignal ViewPositionChangeOverlay::endPositionChange(int deltaX, int deltaY) + + Emmited when the user stops dragging the canvas. + The corresponding handler is \c onEndPositionChange. + */ + signal endPositionChange(int deltaX, int deltaY) + + /*! + \qmlproperty var ViewPositionChangeOverlay::canvas + LogGraphCanvas instance. + */ + property var canvas + /*! + \qmlproperty var ViewPositionChangeOverlay::settingsInstance + Settings instance. + */ + property var settingsInstance + /*! + \qmlproperty int ViewPositionChangeOverlay::prevX + The x coordinate (on the mousearea) at the last change of the canvas position. + */ + property int prevX + /*! + \qmlproperty int ViewPositionChangeOverlay::prevY + The y coordinate (on the mousearea) at the last change of the canvas position. + */ + property int prevY + /*! + \qmlproperty int ViewPositionChangeOverlay::precision + Precision of the (on canvas) position be set. + */ + property int precision + + MouseArea { + id: dragArea + anchors.fill: parent + cursorShape: pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor + property int positionChangeTimer: 0 + + function updatePosition(deltaX, deltaY) { + settingsInstance.xmin = (canvas.px2x(canvas.x2px(settingsInstance.xmin)-deltaX)) + settingsInstance.ymax += deltaY/canvas.yzoom + settingsInstance.ymax = settingsInstance.ymax.toFixed(4) + settingsInstance.changed() + console.log("New pos", settingsInstance.xmin, settingsInstance.ymax) + parent.positionChanged(deltaX, deltaY) + + } + + onPressed: function(mouse) { + prevX = mouse.x + prevY = mouse.y + parent.beginPositionChange() + } + onPositionChanged: function(mouse) { + positionChangeTimer++ + if(positionChangeTimer == 3) { + let deltaX = mouse.x - prevX + let deltaY = mouse.y - prevY + updatePosition(deltaX, deltaY) + prevX = mouse.x + prevY = mouse.y + positionChangeTimer = 0 + } + } + onReleased: function(mouse) { + let deltaX = mouse.x - prevX + let deltaY = mouse.y - prevY + updatePosition(deltaX, deltaY) + parent.endPositionChange(deltaX, deltaY) + } + } +} + From d6a83b0f4bbb45455349ae7bdfb08740b0b95e7c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sat, 7 Oct 2023 23:38:51 +0200 Subject: [PATCH 141/436] Adding the ability to scroll to zoom. --- .../ViewPositionChangeOverlay.qml | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index efcf490..5ac3cb9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -83,10 +83,10 @@ Item { */ property int prevY /*! - \qmlproperty int ViewPositionChangeOverlay::precision - Precision of the (on canvas) position be set. + \qmlproperty double ViewPositionChangeOverlay::baseZoomMultiplier + How much should the zoom be mutliplied/scrolled by for one scroll step (120° on the mouse wheel). */ - property int precision + property double baseZoomMultiplier: 0.1 MouseArea { id: dragArea @@ -99,7 +99,6 @@ Item { settingsInstance.ymax += deltaY/canvas.yzoom settingsInstance.ymax = settingsInstance.ymax.toFixed(4) settingsInstance.changed() - console.log("New pos", settingsInstance.xmin, settingsInstance.ymax) parent.positionChanged(deltaX, deltaY) } @@ -126,6 +125,27 @@ Item { updatePosition(deltaX, deltaY) parent.endPositionChange(deltaX, deltaY) } + onWheel: function(wheel) { + // Scrolling + let scrollSteps = Math.round(wheel.angleDelta.y / 120) + let zoomMultiplier = Math.pow(1+baseZoomMultiplier, Math.abs(scrollSteps)) + // Avoid floating-point rounding errors by removing the zoom *after* + let xZoomDelta = (settingsInstance.xzoom*zoomMultiplier - settingsInstance.xzoom) + let yZoomDelta = (settingsInstance.yzoom*zoomMultiplier - settingsInstance.yzoom) + if(scrollSteps < 0) { // Negative scroll + xZoomDelta *= -1 + yZoomDelta *= -1 + } + let newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(0) + let newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(0) + if(newXZoom == settingsInstance.xzoom) // No change, allow more precision. + newXZoom = (settingsInstance.xzoom+xZoomDelta).toFixed(4) + if(newYZoom == settingsInstance.yzoom) // No change, allow more precision. + newYZoom = (settingsInstance.yzoom+yZoomDelta).toFixed(4) + settingsInstance.xzoom = newXZoom + settingsInstance.yzoom = newYZoom + settingsInstance.changed() + } } } From 3039aade295a11c20931f8095a785a2ee74d0833 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 8 Oct 2023 16:24:16 +0200 Subject: [PATCH 142/436] Fixing some issues with infinity in domains. --- .../qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js | 3 ++- .../qml/eu/ad5001/LogarithmPlotter/js/math/domain.js | 4 ++-- .../qml/eu/ad5001/LogarithmPlotter/js/math/latex.js | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 6417e83..fdd06eb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -26,7 +26,8 @@ var ADDITIONAL_VARCHARS = [ "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", "ₜ","¹","²","³","⁴","⁵","⁶", "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀" + "₄","₅","₆","₇","₈","₉","₀", + "∞" ] function Instruction(type, value) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js index 25f04d2..3586bc0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js @@ -437,8 +437,8 @@ class UnionDomain extends Domain { static import(frm) { var domains = frm.trim().split("∪") if(domains.length == 1) domains = frm.trim().split("U") // Fallback - var dom1 = parseDomain(domains.pop()) - var dom2 = parseDomain(domains.join('∪')) + var dom2 = parseDomain(domains.pop()) + var dom1 = parseDomain(domains.join('∪')) return dom1.union(dom2) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 39461fd..b52a19e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -114,7 +114,7 @@ function variable(vari, wrapIn$ = false) { "ₜ","¹","²","³","⁴","⁵","⁶", "⁷","⁸","⁹","⁰","₁","₂","₃", "₄","₅","₆","₇","₈","₉","₀", - "pi"] + "pi", "∞"] let equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta","\\eta", "\\pi","\\theta","\\kappa","\\lambda","\\mu","\\xi","\\rho", "\\sigma","\\sigma","\\tau","\\phi","\\chi","\\psi","\\omega", @@ -124,7 +124,7 @@ function variable(vari, wrapIn$ = false) { "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", - "\\pi"] + "\\pi", "\\infty"] if(wrapIn$) for(let i = 0; i < unicodechars.length; i++) { if(vari.includes(unicodechars[i])) From 9f2b08b938cb84f415043c8b0eacb925d61cdd48 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 8 Oct 2023 16:31:01 +0200 Subject: [PATCH 143/436] =?UTF-8?q?Fixing=20"Unknown=20variable=20?= =?UTF-8?q?=E2=88=9E."=20message.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It occured when using a domain with the infinity symbol. --- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index fdd06eb..e118ec3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -692,7 +692,7 @@ TokenStream.prototype.isConst = function () { var i = startPos; for (; i < this.expression.length; i++) { var c = this.expression.charAt(i); - if (c.toUpperCase() === c.toLowerCase()) { + if (c.toUpperCase() === c.toLowerCase() && !ADDITIONAL_VARCHARS.includes(c)) { if (i === this.pos || (c !== '_' && c !== '.' && (c < '0' || c > '9'))) { break; } From 7408520819cd9e6e8e66371d2b5493608e75d151 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 8 Oct 2023 17:00:12 +0200 Subject: [PATCH 144/436] Reworking continuous functions' rendering to make it faster. + Diminishing pixel precision from 1 to 10. + The change is barely noticable by the human eye in most functions. + Reworked domain checking to keep the pixel perfect precision. The only visual degradations are functions with very high y variations for very small x variations (like cos and sin on log scale). --- .../LogarithmPlotter/js/objs/function.js | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index 80ebe3c..0ca4665 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -115,9 +115,9 @@ class Function extends Common.ExecutableObject { static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { // Reusable in other objects. // Drawing small traits every 0.2px - var pxprecision = 1 + var pxprecision = 10 var previousX = canvas.px2x(0) - var previousY; + var previousY = null; if(definitionDomain instanceof MathLib.SpecialDomain && definitionDomain.moveSupported) { // Point based functions. previousX = definitionDomain.next(previousX) @@ -147,17 +147,42 @@ class Function extends Common.ExecutableObject { ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) } } else { - previousY = expr.execute(previousX) - for(var px = pxprecision; px < canvas.canvasSize.width; px += pxprecision) { - var currentX = canvas.px2x(px) - var currentY = expr.execute(currentX) - if((definitionDomain.includes(currentX) || definitionDomain.includes(previousX)) && - (destinationDomain.includes(currentY) || destinationDomain.includes(previousY)) && - Math.abs(previousY-currentY)<100) { - canvas.drawLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) + if(definitionDomain.includes(previousX)) + // PreviousY at the start of the canvas + previousY = expr.execute(previousX) + for(let px = pxprecision; px < canvas.canvasSize.width; px += pxprecision) { + let currentX = canvas.px2x(px) + if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { + // Should draw up to currentX, but NOT at previousX. + // Need to find the starting point. + let tmpPx = px-pxprecision + do { + tmpPx++; + previousX = canvas.px2x(tmpPx) + } while(!definitionDomain.includes(previousX)) + // Recaclulate previousY + previousY = expr.execute(previousX) + } else if(!definitionDomain.includes(currentX)) { + // Next x is NOT in the definition domain. + // Augmenting the pixel precision until this condition is fulfilled. + let tmpPx = px + do { + tmpPx--; + currentX = canvas.px2x(tmpPx) + } while(!definitionDomain.includes(currentX) && currentX != previousX) + } + if(definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { + let currentY = expr.execute(currentX) + if(destinationDomain.includes(currentY)) { + if(previousY != null && destinationDomain.includes(previousY)) { + canvas.drawLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) + } } - previousX = currentX - previousY = currentY + previousY = currentY + } else { + previousY = null // Last y was invalid, so let's not draw anything from it. + } + previousX = canvas.px2x(px) } } } From 999999832a6beaf5b8ee03a61f2bd2b581c857ee Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 8 Oct 2023 17:22:21 +0200 Subject: [PATCH 145/436] Taking edge cases into account into new drawing system. --- .../qml/eu/ad5001/LogarithmPlotter/js/objs/function.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index 0ca4665..a1dca1f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -147,8 +147,12 @@ class Function extends Common.ExecutableObject { ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) } } else { + // Use max precision if function is trigonometrical on log scale. + let exprString = expr.expr + if(exprString.includes("sin") || exprString.includes("cos") || exprString.includes("tan")) + pxprecision = (canvas.logscalex || exprString.includes("tan")) ? 1 : 3 + // Calculate the previousY at the start of the canvas if(definitionDomain.includes(previousX)) - // PreviousY at the start of the canvas previousY = expr.execute(previousX) for(let px = pxprecision; px < canvas.canvasSize.width; px += pxprecision) { let currentX = canvas.px2x(px) @@ -171,10 +175,12 @@ class Function extends Common.ExecutableObject { currentX = canvas.px2x(tmpPx) } while(!definitionDomain.includes(currentX) && currentX != previousX) } + // This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...) + let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.canvasSize.height)) if(definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { let currentY = expr.execute(currentX) if(destinationDomain.includes(currentY)) { - if(previousY != null && destinationDomain.includes(previousY)) { + if(previousY != null && destinationDomain.includes(previousY) && Math.abs(previousY-currentY) < maxvariation) { canvas.drawLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) } } From 9879e7fbc9c9b98f813dbb57895b1799bdc4c766 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 8 Oct 2023 18:34:09 +0200 Subject: [PATCH 146/436] Fixing changelog --- .../ad5001/LogarithmPlotter/Popup/Changelog.qml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index 0288b8a..54ef3af 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -32,7 +32,7 @@ Popup { id: changelogPopup x: (parent.width-width)/2 y: Math.max(20, (parent.height-height)/2) - width: changelog.width+40 + width: 800 height: Math.min(parent.height-40, 500) modal: true focus: true @@ -44,33 +44,42 @@ Popup { */ property bool changelogNeedsFetching: true - onAboutToShow: if(changelogNeedsFetching) Helper.fetchChangelog() + onAboutToShow: if(changelogNeedsFetching) { + Helper.fetchChangelog() + } Connections { target: Helper function onChangelogFetched(chl) { changelogNeedsFetching = false; changelog.text = chl + changelogView.contentItem.implicitHeight = changelog.height + // console.log(changelog.height, changelogView.contentItem.implicitHeight) } } ScrollView { + id: changelogView anchors.top: parent.top anchors.topMargin: 10 anchors.left: parent.left anchors.leftMargin: 10 + anchors.right: parent.right + anchors.rightMargin: 10 anchors.bottom: doneBtn.top anchors.bottomMargin: 10 clip: true + Label { id: changelog color: sysPalette.windowText + width: 760 + wrapMode: Text.WordWrap textFormat: TextEdit.MarkdownText text: qsTr("Fetching changelog...") onLinkActivated: Qt.openUrlExternally(link) - } } From a66ccd131935673433433d3475bb417d383925fb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 8 Oct 2023 18:34:51 +0200 Subject: [PATCH 147/436] Changing version to v0.4.1 --- LogarithmPlotter/__init__.py | 4 ++-- mac/Info.plist | 2 +- scripts/package-macosx.sh | 2 +- win/installer.nsi | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index bef6d4a..9ca64ea 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,8 +17,8 @@ """ from shutil import which -__VERSION__ = "0.4.0" -is_release = True +__VERSION__ = "0.4.1" +is_release = False # Check if development version, if so get the date of the latest git patch diff --git a/mac/Info.plist b/mac/Info.plist index 22fdeca..b0e7099 100644 --- a/mac/Info.plist +++ b/mac/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.4.0 + 0.4.1 NSHighResolutionCapable UTExportedTypeDeclarations diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index bae5c03..d957a82 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -VERSION=0.4.0 +VERSION=0.4.1 title="LogarithmPlotter v${VERSION} Setup" finalDMGName="LogarithmPlotter-v${VERSION}-setup.dmg" applicationName=LogarithmPlotter diff --git a/win/installer.nsi b/win/installer.nsi index 395aa6b..e82c1c5 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -11,7 +11,7 @@ Unicode True !define PROG_ID "LogarithmPlotter.File.1" !define DEV_NAME "Ad5001" !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" -!define VERSION_SHORT "0.4.0" +!define VERSION_SHORT "0.4.1" !define APP_VERSION "${VERSION_SHORT}.0" !define COPYRIGHT "Ad5001 (c) 2023" !define DESCRIPTION "Create graphs with logarithm scales." From 4fe1086d681f774963aa59f024e89ab7619b3b94 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 8 Oct 2023 22:36:23 +0200 Subject: [PATCH 148/436] Adding new behavior for object creation to default on picker when pickable. --- .../ObjectLists/ObjectCreationGrid.qml | 39 ++++++++++++++++--- .../ObjectLists/ObjectLists.qml | 1 + .../LogarithmPlotter/PickLocationOverlay.qml | 11 ++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 133971d..0c632e7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -34,6 +34,22 @@ Column { id: createRow property var objectEditor property var objectLists + property var posPicker + + /*! + \qmlmethod int ObjectCreationGrid::openEditorDialog(var obj) + Opens the editor dialog for an object \c obj. + */ + function openEditorDialog(obj) { + // Open editor + console.log(obj, obj.prototype) + objectEditor.obj = obj + objectEditor.objType = obj.type + objectEditor.objIndex = Objects.currentObjects[obj.type].indexOf(obj) + objectEditor.open() + // Disconnect potential link + posPicker.picked.disconnect(openEditorDialog) + } Label { id: createTitle @@ -89,13 +105,26 @@ Column { ToolTip.text: label.text onClicked: { - var newObj = Objects.createNewRegisteredObject(modelData) + let newObj = Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() - objectEditor.obj = Objects.currentObjects[modelData][Objects.currentObjects[modelData].length - 1] - objectEditor.objType = modelData - objectEditor.objIndex = Objects.currentObjects[modelData].length - 1 - objectEditor.open() + + let hasXProp = newObj.constructor.properties().hasOwnProperty('x') + let hasYProp = newObj.constructor.properties().hasOwnProperty('y') + if(hasXProp || hasYProp) { + // Open picker + posPicker.objType = newObj.type + posPicker.objName = newObj.name + posPicker.pickX = hasXProp + posPicker.pickY = hasYProp + posPicker.propertyX = 'x' + posPicker.propertyY = 'y' + posPicker.visible = true + posPicker.picked.connect(openEditorDialog) + } else { + // Open editor + openEditorDialog(newObj) + } } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index a964d94..03b04c6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -110,6 +110,7 @@ ScrollView { width: objectsListView.width objectEditor: objEditor objectLists: objectListList + posPicker: positionPicker } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index e26da61..565069a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -39,6 +39,14 @@ Item { visible: false clip: true + /*! + \qmlsignal PickLocationOverlay::picked(var obj) + + Emitted when a location has been picked + The corresponding handler is \c onPicked. + */ + signal picked(var obj) + /*! \qmlproperty var PickLocationOverlay::canvas logGraphCanvas instance. @@ -116,6 +124,7 @@ Item { obj[propertyY] = newValueY obj.update() objectLists.update() + pickerRoot.picked(obj) } else if(parent.userPickX) { history.addToHistory(new HistoryLib.EditedProperty( objName, objType, propertyX, obj[propertyX], newValueX @@ -123,6 +132,7 @@ Item { obj[propertyX] = newValueX obj.update() objectLists.update() + pickerRoot.picked(obj) } else if(parent.userPickY) { history.addToHistory(new HistoryLib.EditedProperty( objName, objType, propertyY, obj[propertyY], newValueY @@ -130,6 +140,7 @@ Item { obj[propertyY] = newValueY obj.update() objectLists.update() + pickerRoot.picked(obj) } } pickerRoot.visible = false; From 7542d631217e8112b2c9caabcc31039608055a97 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 9 Oct 2023 17:20:32 +0200 Subject: [PATCH 149/436] Adding new characters to insert chars popup. --- .../LogarithmPlotter/Popup/InsertCharacter.qml | 1 + .../eu/ad5001/LogarithmPlotter/js/math/domain.js | 15 +++++++++++++++ setup.py | 3 +++ snapcraft.yaml | 2 +- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index 57f7e7d..d893d43 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -42,6 +42,7 @@ Popup { columns: 7 property var insertChars: [ + "∞","π","ℝ","ℕ","ℤ","∪","∩", "α","β","γ","δ","ε","ζ","η", "π","θ","κ","λ","μ","ξ","ρ", "ς","σ","τ","φ","χ","ψ","ω", diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js index 3586bc0..b27dbc6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js @@ -72,11 +72,13 @@ class Domain { case "RP": case "R+": case "ℝ⁺": + case "ℝ+": return Domain.RP break; case "RM": case "R-": case "ℝ⁻": + case "ℝ-": return Domain.RM break; case "RPE": @@ -85,6 +87,8 @@ class Domain { case "R*+": case "ℝ*⁺": case "ℝ⁺*": + case "ℝ*+": + case "ℝ+*": return Domain.RPE break; case "RME": @@ -93,16 +97,21 @@ class Domain { case "R*-": case "ℝ⁻*": case "ℝ*⁻": + case "ℝ-*": + case "ℝ*-": return Domain.RME break; case "ℕ": case "N": case "ZP": + case "Z+": case "ℤ⁺": + case "ℤ+": return Domain.N break; case "NLOG": case "ℕˡᵒᵍ": + case "ℕLOG": return Domain.NLog break; case "NE": @@ -111,12 +120,15 @@ class Domain { case "N+": case "ℕ*": case "ℕ⁺": + case "ℕ+": case "ZPE": case "ZEP": case "Z+*": case "Z*+": case "ℤ⁺*": case "ℤ*⁺": + case "ℤ+*": + case "ℤ*+": return Domain.NE break; case "Z": @@ -126,6 +138,7 @@ class Domain { case "ZM": case "Z-": case "ℤ⁻": + case "ℤ-": return Domain.ZM break; case "ZME": @@ -134,6 +147,8 @@ class Domain { case "Z*-": case "ℤ⁻*": case "ℤ*⁻": + case "ℤ-*": + case "ℤ*-": return Domain.ZME break; case "ZE": diff --git a/setup.py b/setup.py index 8e78439..841664c 100644 --- a/setup.py +++ b/setup.py @@ -67,6 +67,9 @@ Operating System :: POSIX :: BSD Operating System :: POSIX :: Linux Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 +Programming Language :: Python :: 3.10 +Programming Language :: Python :: 3.11 +Programming Language :: Python :: 3.12 Programming Language :: Python :: Implementation :: CPython Topic :: Utilities Topic :: Scientific/Engineering diff --git a/snapcraft.yaml b/snapcraft.yaml index 7be0d43..f052558 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,6 +1,6 @@ name: logarithmplotter title: LogarithmPlotter -version: '0.4.0' +version: '0.4.1' summary: 2D logarithmic-scaled plotter software to create asymptotic Bode plots confinement: strict base: core20 From bc35b18da06464a924f75b101621c0686be7d962 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 9 Oct 2023 17:55:06 +0200 Subject: [PATCH 150/436] Insert character popup's characters are now contextually aware. --- .../History/HistoryBrowser.qml | 1 + .../ObjectLists/Editor/CustomPropertyList.qml | 15 +++++-- .../ObjectLists/Editor/Dialog.qml | 1 + .../Popup/InsertCharacter.qml | 45 ++++++++++++++++--- .../Setting/ExpressionEditor.qml | 2 + .../LogarithmPlotter/Setting/TextSetting.qml | 6 +++ .../eu/ad5001/LogarithmPlotter/Settings.qml | 2 + 7 files changed, 62 insertions(+), 10 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index 16feace..b6562e3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -54,6 +54,7 @@ Item { anchors.right: parent.right anchors.top: parent.top placeholderText: qsTr("Filter...") + category: "all" } ScrollView { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index a800c6e..63acf76 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -103,14 +103,21 @@ Repeater { height: 30 label: propertyLabel icon: `settings/custom/${propertyIcon}.svg` - isDouble: propertyType == 'number' + isDouble: propertyType == "number" defValue: obj[propertyName] == null ? '' : obj[propertyName].toString() + category: { + return { + "Domain": "domain", + "string": "all", + "number": "all" + }[propertyType] + } onChanged: function(newValue) { try { var newValueParsed = { - 'Domain': () => MathLib.parseDomain(newValue), - 'string': () => newValue, - 'number': () => parseFloat(newValue) + "Domain": () => MathLib.parseDomain(newValue), + "string": () => newValue, + "number": () => parseFloat(newValue) }[propertyType]() // Ensuring old and new values are different to prevent useless adding to history. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index a9b8052..44e4b73 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -107,6 +107,7 @@ Popup.BaseDialog { height: 30 label: qsTr("Name") icon: "common/label.svg" + category: "name" width: dlgProperties.width value: objEditor.obj.name onChanged: function(newValue) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index d893d43..fbd1a64 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -31,8 +31,19 @@ Popup { signal selected(string character) + /*! + \qmlproperty string InsertCharacter::category + Type of special character to insert. + Possible values: + - expression + - domain + - name + - all + */ + property string category: 'all' + width: 280 - height: insertGrid.insertChars.length/insertGrid.columns*(width/insertGrid.columns) + height: Math.ceil(insertGrid.insertChars.length/insertGrid.columns)*(width/insertGrid.columns)+5 modal: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent @@ -41,18 +52,40 @@ Popup { width: parent.width columns: 7 - property var insertChars: [ - "∞","π","ℝ","ℕ","ℤ","∪","∩", + property var insertCharsExpression: [ + "∞","π","¹","²","³","⁴","⁵", + "⁶","⁷","⁸","⁹","⁰" + ] + + property var insertCharsDomain: [ + "∅","∪","∩","∖","ℝ","ℕ","ℤ", + "⁺","⁻",...insertCharsExpression + ] + + property var insertCharsName: [ "α","β","γ","δ","ε","ζ","η", "π","θ","κ","λ","μ","ξ","ρ", "ς","σ","τ","φ","χ","ψ","ω", "Γ","Δ","Θ","Λ","Ξ","Π","Σ", "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", - "ₜ","¹","²","³","⁴","⁵","⁶", - "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀" + "ₜ","₁","₂","₃","₄","₅","₆", + "₇","₈","₉","₀" ] + + property var insertCharsAll: [ + ...insertCharsName, ...insertCharsDomain + ] + + property var insertChars: { + return { + "expression": insertCharsExpression, + "domain": insertCharsDomain, + "name": insertCharsName, + "all": insertCharsAll + }[insertPopup.category] + } + Repeater { model: parent.insertChars.length diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 897abda..5a758b5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -507,6 +507,8 @@ Item { x: Math.round((parent.width - width) / 2) y: Math.round((parent.height - height) / 2) + category: "expression" + onSelected: function(c) { editor.insert(editor.cursorPosition, c) insertPopup.close() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 539ea96..00c1347 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -49,6 +49,12 @@ Item { If true, the input is being parsed an double before being emitting the \a changed signal. */ property bool isDouble: false + /*! + \qmlproperty bool TextSetting::category + Type of special character to insert from the popup. + \sa InsertCharacter::category + */ + property alias category: insertPopup.category /*! \qmlproperty double TextSetting::min Minimum value for numbers that can be entered into the input. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 39c508f..ceca22f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -255,6 +255,7 @@ ScrollView { Setting.TextSetting { id: xAxisStep height: 30 + category: "expression" label: qsTr("X Axis Step") icon: "settings/xaxisstep.svg" width: settings.settingWidth @@ -269,6 +270,7 @@ ScrollView { Setting.TextSetting { id: yAxisStep height: 30 + category: "expression" label: qsTr("Y Axis Step") icon: "settings/yaxisstep.svg" width: settings.settingWidth From cf754a7a34db11e6c91e00a35f5168c5aa271eb8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 9 Oct 2023 18:37:28 +0200 Subject: [PATCH 151/436] Better handling of constants in simplified expressions. --- .../ad5001/LogarithmPlotter/js/expr-eval.js | 23 ++++++++++--------- .../ad5001/LogarithmPlotter/js/math/common.js | 7 +++++- .../LogarithmPlotter/js/math/expression.js | 4 ++-- .../eu/ad5001/LogarithmPlotter/js/utils.js | 16 +++++++++++++ README.md | 2 +- 5 files changed, 37 insertions(+), 15 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index e118ec3..ae689e8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -521,7 +521,7 @@ Expression.prototype.substitute = function (variable, expr) { }; Expression.prototype.evaluate = function (values) { - values = values || {}; + values = Object.assign({}, values, this.parser.consts) return evaluate(this.tokens, this, values); }; @@ -541,8 +541,9 @@ Expression.prototype.variables = function (options) { var vars = []; getSymbols(this.tokens, vars, options); var functions = this.functions; + var consts = this.parser.consts return vars.filter(function (name) { - return !(name in functions); + return !(name in functions) && !(name in consts); }); }; @@ -580,7 +581,7 @@ function TokenStream(parser, expression) { this.unaryOps = parser.unaryOps; this.binaryOps = parser.binaryOps; this.ternaryOps = parser.ternaryOps; - this.consts = parser.consts; + this.builtinConsts = parser.builtinConsts; this.expression = expression; this.savedPosition = 0; this.savedCurrent = null; @@ -700,8 +701,8 @@ TokenStream.prototype.isConst = function () { } if (i > startPos) { var str = this.expression.substring(startPos, i); - if (str in this.consts) { - this.current = this.newToken(TNUMBER, this.consts[str]); + if (str in this.builtinConsts) { + this.current = this.newToken(TNUMBER, this.builtinConsts[str]); this.pos += str.length; return true; } @@ -1792,12 +1793,12 @@ class Parser { join: arrayJoin }; - this.consts = { - E: Math.E, - PI: Math.PI, - 'true': true, - 'false': false - }; + // These constants will automatically be replaced the MOMENT they are parsed. + // (Original consts from the parser) + this.builtinConsts = {}; + // These consts will only be replaced when the expression is evaluated. + this.consts = {} + } parse(expr) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 59297d8..297887b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -26,13 +26,17 @@ const DERIVATION_PRECISION = 0.1 var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually "pi": Math.PI, + "PI": Math.PI, "π": Math.PI, "inf": Infinity, "infinity": Infinity, "Infinity": Infinity, "∞": Infinity, "e": Math.E, - "E": Math.E + "E": Math.E, + "true": true, + "false": false + } var currentVars = {} @@ -54,3 +58,4 @@ parser.functions.derivative = function(f, variable, x) { f = parser.parse(f).toJSFunction(variable, currentVars) return (f(x+DERIVATION_PRECISION/2)-f(x-DERIVATION_PRECISION/2))/DERIVATION_PRECISION } + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index 9c9ae49..01b25b9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -27,8 +27,8 @@ */ class Expression { constructor(expr) { - this.expr = expr - this.calc = C.parser.parse(expr).simplify() + this.expr = Utils.exponentsToExpression(expr) + this.calc = C.parser.parse(this.expr).simplify() this.cached = this.isConstant() this.cachedValue = this.cached && this.allRequirementsFullfilled() ? this.calc.evaluate(C.currentObjectsByName) : null this.latexMarkup = Latex.expression(this.calc.tokens) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index 9121661..8ca3a69 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -62,6 +62,11 @@ var powerpos = { "z": "ᶻ" } +var exponents = [ + "⁰","¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹" +] +var exponentReg = new RegExp('(['+exponents.join('')+']+)', 'g') + var indicepos = { "-": "₋", "+": "₊", @@ -351,3 +356,14 @@ function getRandomColor() { function escapeHTML(str) { return str.replace(/&/g,'&').replace(//g,'>') ; } + + + +/** + * Parses exponents and replaces them with expression values + * @param {string} expression - The expression to replace in. + * @return {string} The parsed expression + */ +function exponentsToExpression(expression) { + return expression.replace(exponentReg, (m, exp) => '^' + exp.split('').map((x) => exponents.indexOf(x)).join('')) +} diff --git a/README.md b/README.md index e75daba..ba1f3b1 100644 --- a/README.md +++ b/README.md @@ -79,4 +79,4 @@ Language files translations located at LogarithmPlotter/i18n are licensed under LogarithmPlotter includes [expr-eval](https://github.com/silentmatt/expr-eval) a port of [ndef.parser](https://web.archive.org/web/20111023001618/http://www.undefined.ch/mparser/index.html) by Raphael Graf <r@undefined.ch>, ported to javascript by Matthew Crumley <email@matthewcrumley.com> (http://silentmatt.com/), and then to QMLJS by Ad5001. -The code is licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). +The specific file (LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js) is licensed under the [MIT License](https://raw.githubusercontent.com/silentmatt/expr-eval/master/LICENSE.txt). From 038dd9f4a8e47f183eb46430fe50538eaaf94176 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 9 Oct 2023 18:50:34 +0200 Subject: [PATCH 152/436] Fixing the (previously very broken) text renderer when using symbols. --- .../qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml | 4 ++-- .../eu/ad5001/LogarithmPlotter/js/math/expression.js | 1 + .../qml/eu/ad5001/LogarithmPlotter/js/utils.js | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index bd10c29..55ef234 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -301,7 +301,7 @@ Canvas { } else { for(var x = 1; x < drawMaxX; x += 1) { var drawX = x*xaxisstep1 - var txtX = xaxisstepExpr.simplify(x) + var txtX = xaxisstepExpr.simplify(x).replace(/^\((.+)\)$/, '$1') var textSize = measureText(ctx, txtX, 6).height drawVisibleText(ctx, txtX, x2px(drawX)-4, axisxpx+textsize/2+textSize) drawVisibleText(ctx, '-'+txtX, x2px(-drawX)-4, axisxpx+textsize/2+textSize) @@ -311,7 +311,7 @@ Canvas { if(showygrad) { for(var y = 0; y < drawMaxY; y += 1) { var drawY = y*yaxisstep1 - var txtY = yaxisstepExpr.simplify(y) + var txtY = yaxisstepExpr.simplify(y).replace(/^\((.+)\)$/, '$1') var textSize = ctx.measureText(txtY).width drawVisibleText(ctx, txtY, axisypx-6-textSize, y2px(drawY)+4+(10*(y==0))) if(y != 0) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index 01b25b9..f4deb0d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -68,6 +68,7 @@ class Expression { simplify(x) { var expr = this.calc.substitute('x', x).simplify() + print(this.expr, this.calc.substitute('x', x), expr) if(expr.evaluate() == 0) return '0' var str = Utils.makeExpressionReadable(expr.toString()); if(str != undefined && str.match(/^\d*\.\d+$/)) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index 8ca3a69..624b3a5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -256,14 +256,14 @@ function makeExpressionReadable(str) { // Other [/ \* /g, '×'], [/ \^ /g, '^'], - [/\^\(([^\^]+)\)/g, function(match, p1) { return textsup(p1) }], - [/\^([^ "]+)/g, function(match, p1) { return textsup(p1) }], - [/_\(([^_]+)\)/g, function(match, p1) { return textsub(p1) }], - [/_([^ "]+)/g, function(match, p1) { return textsub(p1) }], + [/\^\(([\d\w+-]+)\)/g, function(match, p1) { return textsup(p1) }], + [/\^([\d\w+-]+)/g, function(match, p1) { return textsup(p1) }], + [/_\(([\d\w+-]+)\)/g, function(match, p1) { return textsub(p1) }], + [/_([\d\w+-]+)/g, function(match, p1) { return textsub(p1) }], [/\[([^\[\]]+)\]/g, function(match, p1) { return textsub(p1) }], [/(\d|\))×/g, '$1'], //[/×(\d|\()/g, '$1'], - [/[^a-z]\(([^)(+.\/-]+)\)/g, "$1"], + [/([^a-z])\(([^)(+.\/-]+)\)/g, "$1×$2"], [/integral\((.+),\s?(.+),\s?("|')(.+)("|'),\s?("|')(.+)("|')\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { if(a.length < b.length) { return `∫${textsub(a)}${textsup(b)} ${body} d${by}` From 2b5d442d3af54f64cd0130048663a665cb8cf2a9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 9 Oct 2023 20:29:21 +0200 Subject: [PATCH 153/436] Changing v0.4.1 to v0.5.0 considering the number of changes. --- LogarithmPlotter/__init__.py | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/expression.js | 1 - mac/Info.plist | 2 +- scripts/package-macosx.sh | 2 +- snapcraft.yaml | 2 +- win/installer.nsi | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 9ca64ea..cbf8ecc 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,7 +17,7 @@ """ from shutil import which -__VERSION__ = "0.4.1" +__VERSION__ = "0.5.0" is_release = False diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index f4deb0d..01b25b9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -68,7 +68,6 @@ class Expression { simplify(x) { var expr = this.calc.substitute('x', x).simplify() - print(this.expr, this.calc.substitute('x', x), expr) if(expr.evaluate() == 0) return '0' var str = Utils.makeExpressionReadable(expr.toString()); if(str != undefined && str.match(/^\d*\.\d+$/)) { diff --git a/mac/Info.plist b/mac/Info.plist index b0e7099..d7c0c50 100644 --- a/mac/Info.plist +++ b/mac/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.4.1 + 0.5.0 NSHighResolutionCapable UTExportedTypeDeclarations diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index d957a82..f7e9cbe 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -VERSION=0.4.1 +VERSION=0.5.0 title="LogarithmPlotter v${VERSION} Setup" finalDMGName="LogarithmPlotter-v${VERSION}-setup.dmg" applicationName=LogarithmPlotter diff --git a/snapcraft.yaml b/snapcraft.yaml index f052558..6610006 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,6 +1,6 @@ name: logarithmplotter title: LogarithmPlotter -version: '0.4.1' +version: '0.5.0' summary: 2D logarithmic-scaled plotter software to create asymptotic Bode plots confinement: strict base: core20 diff --git a/win/installer.nsi b/win/installer.nsi index e82c1c5..7366cdd 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -11,7 +11,7 @@ Unicode True !define PROG_ID "LogarithmPlotter.File.1" !define DEV_NAME "Ad5001" !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" -!define VERSION_SHORT "0.4.1" +!define VERSION_SHORT "0.5.0" !define APP_VERSION "${VERSION_SHORT}.0" !define COPYRIGHT "Ad5001 (c) 2023" !define DESCRIPTION "Create graphs with logarithm scales." From 062fde6b1682238e9560dbeefeacb959b4a1ac1d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 9 Oct 2023 22:26:50 +0200 Subject: [PATCH 154/436] Updating build script for newest pyinstaller version. --- scripts/build-wine.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index 7ff3394..53dd11c 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -21,10 +21,10 @@ DRIVEC="${WINEPREFIX:-$HOME/.wine}/drive_c" PYSIDE6PATH="${PYSIDE6PATH%$'\r'}" PYSIDE6PATH="${PYSIDE6PATH//\\/\/}" PYSIDE6PATH="${PYSIDE6PATH//C:/$DRIVEC}" -cp "$PYSIDE6PATH/Qt6ShaderTools.dll" dist/logarithmplotter/PySide6/ +cp "$PYSIDE6PATH/Qt6ShaderTools.dll" dist/logarithmplotter/_internal/PySide6/ # Remove QtWebEngine -rm dist/logarithmplotter/PySide6/Qt6WebEngineCore.dll +rm dist/logarithmplotter/_internal/PySide6/Qt6WebEngineCore.dll # Remove the QtQuick styles that are unused -rm -rf dist/logarithmplotter/PySide6/qml/QtQuick/Controls/{Imagine,Material,designer} +rm -rf dist/logarithmplotter/_internal/PySide6/qml/QtQuick/Controls/{Imagine,Material,designer} From 4b692894f2aebcfc59cb7439f160cf8ca970acff Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 9 Oct 2023 23:27:30 +0200 Subject: [PATCH 155/436] Removing old and unused bits for previously planned new parser, that would have remained unused. Some bits (like the tokenizer and the reference) are still used for the syntax highlighting and autocomplete though. --- .../ad5001/LogarithmPlotter/js/parsing/ast.js | 663 ------------------ .../LogarithmPlotter/js/parsing/builder.js | 47 -- .../LogarithmPlotter/js/parsing/parsing.js | 2 + 3 files changed, 2 insertions(+), 710 deletions(-) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js deleted file mode 100644 index eca0f78..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/ast.js +++ /dev/null @@ -1,663 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -.pragma library - -.import "reference.js" as Reference - -const DERIVATION_PRECISION = 0.01 - -const OPERATION_PRIORITY = { - "+": 10, "-": 10, - "*": 20, "/": 20 -} - -enum ASEType { - UNKNOWN, - VARIABLE, - NUMBER, - STRING, - FUNCTION, - CONSTANT, - OPERATION, - NEGATION // Example: -x. -} - -class AbstractSyntaxElement { - type = ASEType.UNKNOWN; - - execute(variables) { - return null; - } - simplify() { - return this; - } - derivate(variable) { - return this; - } - integrate(variable) { - return this; - } - toEditableString() { - return ""; - } - toLatex() { - return ""; - } - isConstant() { - return true; - } -} - -class Variable extends AbstractSyntaxElement { - type = ASEType.VARIABLE; - - constructor(variableName) { - this.varName = variableName; - } - - execute(variables) { - if(variables.includes(this.varName)) { - return variables[this.varName]; - } else { - throw new EvalError("Unknown variable " + this.varName + "."); - } - } - - derivate(variable) { - if(variable == this.varName) - return new NumberElement(1); - return this; - } - - integrate(variable) { - if(variable == this.varName) - // ^2/2 - return new Operation(new Operation(this, '^', new NumberElement(2)), '/', new NumberElement(2)); - return this; - } - - toEditableString() { - return this.varName; - } - - toLatex() { - return this.varName; - } - - isConstant() { - return false; - } -} - -class ArrayVariable extends Variable { - constructor(arrayName, astIndex) { - super(arrayName + "[" + astIndex.toEditableString() + "]") - this.arrayName = arrayName; - this.astIndex = astIndex; - } - - execute(variables) { - if(variables.includes(this.arrayName)) { - let index = this.astIndex.execute(variables) - if(index % 1 != 0 || index < 0) { // Float index. - throw new EvalError("Non-integer array index " + index + " used as array index for " + this.varName + "."); - } else if(variables[this.arrayName].length <= index) { - throw new EvalError("Out-of-range index " + index + " used as array index for " + this.varName + "."); - } else { - return variables[this.arrayName][index]; - } - } else { - throw new EvalError("Unknown variable " + this.varName + "."); - } - - toLatex() { - return this.varName; - } - } - - simplify() { - return new ArrayVariable(this.arrayName, this.astIndex.simplify()); - } - - toLatex() { - return this.arrayName + '\\left[' + this.astIndex.toLatex() + '\\right]'; - } - - isConstant() { - return false; - } -} - - -class Constant extends Variable { - type = ASEType.CONSTANT; - - constructor(constant) { - super(constant) - } - - execute(variables) { - if(Reference.CONSTANTS_LIST.includes(this.varName)) { - return Reference.CONSTANTS[this.varName]; - } else { - throw new EvalError("Unknown constant " + this.varName + "."); - } - } - - derivate(variable) { - if(variable == this.varName) - return new NumberElement(0); - return this; - } - - integrate(variable) { - return new Operation(new Variable(variable), '^', this); - } - - toEditableString() { - return this.varName; - } - - toLatex() { - return this.varName; - } - - isConstant() { - return true; - } -} - -class NumberElement extends AbstractSyntaxElement { - type = ASEType.NUMBER; - - constructor(number) { - this.value = parseFloat(number); - } - - derivate(variable) { - return new NumberElement(0); - } - - integrate(variable) { - return new Variable(variable); - } - - toEditableString() { - return this.value.toString(); - } - - toLatex() { - return this.value.toString(); - } - - isConstant() { - return true; - } -} - -class StringElement extends AbstractSyntaxElement { - type = ASEType.STRING; - - constructor(str) { - this.str = str; - } - - execute(variables) { - return this.str - } - - derivate(variable) { - return this; - } - - integrate(variable) { - return this; - } - - toEditableString() { - return '"' + this.str + '"'; - } - - toLatex() { - return this.str; - } - - isConstant() { - return true; - } -} - -class FunctionElement extends AbstractSyntaxElement { - type = ASEType.FUNCTION; - - constructor(functionName, astArguments) { - this.function = functionName; - this.args = astArguments; - } - - execute(variables) { - if(this.function == "derivate") { - return executeDerivative(variables) - } else if(this.function == "integrate") { - return executeIntegral(variables) - } else if(Reference.FUNCTIONS_LIST.includes(this.function)) { - let args = this.args.map(arg => arg.execute(variables)); - return Reference.FUNCTIONS[this.function](...args); - } else { - throw new EvalError("Unknown function " + this.function + "."); - } - } - - executeDerivative(variables) { - // Calculate derivation. - if(this.args.length == 2) - if(this.args[1] instanceof Variable) { - let d = this.args[1].varName; // derivative variable name. - if(Object.keys(variables).includes(d)) { - let plus = this.args[0].execute(Object.assign({}, variables, {d: variables[d]+DERIVATION_PRECISION/2})); - let min = this.args[0].execute(Object.assign({}, variables, {d: variables[d]-DERIVATION_PRECISION/2})); - return (plus-min)/DERIVATION_PRECISION - } else - throw new EvalError("Undefined variable " + d + "."); - } else - throw new EvalError(`Argument 1 of function derivate must be a variable.`) - else - throw new EvalError(`Function 'derivate' can only have 2 arguments. ${this.args.length} provided.`) - } - - executeIntegral(variables) { - // Calculate integral. - // Using simons rule - // https://en.wikipedia.org/wiki/Simpson%27s_rule - let d, f, a, b; - if(this.args.length == 2) - // Integral(f,var) integral of f by var. - if(this.args[1] instanceof Variable) - if(Object.keys(variables).includes(d)) { - d = this.args[1].varName; // derivative variable name. - if(!Object.keys(variables).includes(d)) - throw new EvalError("Undefined variable " + d + ".") - a = 0; - b = variables[d]; - f = this.args[0].execute; - } else - else - throw new EvalError(`Argument 2 of function derivate must be a variable.`) - else if(this.args.length == 4) - // Integral(a,b,f,var) integral from a to b of f by var. - if(this.args[3] instanceof Variable) - if(Object.keys(variables).includes(d)) { - a = this.args[0].execute(variables); - b = this.args[1].execute(variables); - f = this.args[2].execute; - d = this.args[3].varName; // derivative variable name. - if(!Object.keys(variables).includes(d)) - throw new EvalError("Undefined variable " + d + "."); - } - else - throw new EvalError(`Argument 4 of function derivate must be a variable.`) - else - throw new EvalError(`Function 'derivate' can only have 2 or 4 arguments. ${this.args.length} provided.`) - - // (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) - let f_a = f(Object.assign({}, variables, {d: a})), f_b = f(Object.assign({}, variables, {d: b})); - let f_m = f(Object.assign({}, variables, {d: (a+b)/2})) - return (b-a)/6*(f_a+4*f_m+f_b); - } - - simplify() { - let args = this.args.map(arg => arg.simplify(variables)); - let newFunc = new FunctionElement(this.function, args); - let result; - if(newFunc.isConstant() && (result = newFunc.execute({})) % 1 == 0) { // Simplification (e.g. cos(0), sin(π/2)...) - return new NumberElement(result); - } else { - return newFunc; - } - } - - derivate(variable) { - //TODO: Use DERIVATIVES elements in reference. - return new FunctionElement("derivate", this, variable); - } - - integrate(variable) { - //TODO: Use INTEGRALS elements in reference. - return new FunctionElement("integrate", this, variable); - } - - toEditableString() { - return this.function + '(' + this.args.map(arg => arg.toEditableString()).join(', ') + ')'; - } - - toLatex() { - switch(this.function) { - case "sqrt": - return '\\sqrt{' + this.args.map(arg => arg.toLatex()).join(', ') + '}'; - case "abs": - return '\\left|' + this.args.map(arg => arg.toLatex()).join(', ') + '\\right|'; - case "floor": - return '\\left\\lfloor' + this.args.map(arg => arg.toLatex()).join(', ') + '\\right\\rfloor'; - case "ceil": - return '\\left\\lceil' + this.args.map(arg => arg.toLatex()).join(', ') + '\\right\\rceil'; - default: - return '\\mathrm{' + this.function + '}\\left(' + this.args.map(arg => arg.toLatex()).join(', ') + '\\right)'; - } - } - - isConstant() { - if(this.function == "derivate") - return this.args[0].isConstant(); - else if(this.function == "integrate") - return this.args.length == 4 && this.args[0].isConstant() && this.args[1].isConstant() && this.args[2].isConstant(); - else - return this.args.every(x => x.isConstant()); - } -} - -class Operation extends AbstractSyntaxElement { - type = ASEType.OPERATION; - - constructor(leftHand, operation, rightHand) { - this.leftHand = leftHand; - this.ope = operation; - this.rightHand = rightHand; - } - - evaluate(variables) { - switch(this.ope) { - case '+': - return this.leftHand.evaluate(variables) + this.rightHand.evaluate(variables); - case '-': - return this.leftHand.evaluate(variables) - this.rightHand.evaluate(variables); - case '*': - return this.leftHand.evaluate(variables) * this.rightHand.evaluate(variables); - case '/': - return this.leftHand.evaluate(variables) / this.rightHand.evaluate(variables); - case '%': - return this.leftHand.evaluate(variables) % this.rightHand.evaluate(variables); - case '^': - return Math.pow(this.leftHand.evaluate(variables), this.rightHand.evaluate(variables)); - default: - throw new EvalError("Unknown operator " + ope + "."); - } - } - - simplify() { - let leftHand = this.leftHand.simplify(); - let rightHand = this.rightHand.simplify(); - let newOpe = new Operation(leftHand, this.ope, rightHand); - if(leftHand.isConstant() && rightHand.isConstant() && Math.abs(newOpe.execute({})) < 1000000) { - // Do not simplify to too big numbers - switch(this.ope) { - case '+': - case '-': - case '*': - case '^': - case '%': - return new NumberElement(newOpe.execute({})); - case '/': - if(result % 1 == 0) - return new NumberElement(newOpe.execute({})); - else { - let simplified = simplifyFraction(leftHand.number, rightHand.number) - return new Operation(new NumberElement(simplified[0]), '/', new NumberElement(simplified[1])) - } - return this.leftHand.evaluate(variables) / this.rightHand.evaluate(variables); - return Math.pow(this.leftHand.evaluate(variables), this.rightHand.evaluate(variables)); - default: - throw new EvalError("Unknown operator " + ope + "."); - } - } else { - // Simplifications of +- 0 or *1 - switch(this.ope) { - case '+': - case '-': - if(leftHand.type == ASEType.NUMBER && leftHand.value == 0) - return rightHand; - else if(rightHand.type == ASEType.NUMBER && rightHand.value == 0) { - if(ope == '-') leftHand.value = -leftHand.value; - return leftHand; - } else - return newOpe - case '*': - if((leftHand.type == ASEType.NUMBER && leftHand.value == 0) || (rightHand.type == ASEType.NUMBER && rightHand.value == 0)) - return new NumberElement(0); - else if(leftHand.type == ASEType.NUMBER && leftHand.value == 1) - return rightHand; - else if(rightHand.type == ASEType.NUMBER && rightHand.value == 1) - return leftHand; - else - return newOpe - case '^': - if(rightHand.type == ASEType.NUMBER && rightHand.value == 0) - return new NumberElement(1); - else if(rightHand.type == ASEType.NUMBER && rightHand.value == 1) - return new NumberElement(leftHand.value); - else - return newOpe; - case '/': - if(rightHand.type == ASEType.NUMBER && rightHand.value == 1) - return new NumberElement(leftHand.value); - else - return newOpe; - case '%': - return newOpe; - default: - throw new EvalError("Unknown operator " + ope + "."); - } - } - } - - derivate(variable) { - switch(this.ope) { - case '-': - case '+': - return new Operation(this.leftHand.derivate(variable), this.ope, this.rightHand.derivate(variable)); - case '*': - return new Operation( - new Operation(this.leftHand, '*', this.rightHand.derivate(variable)), - '+', - new Operation(this.leftHand.derivate(variable), '*', this.rightHand), - ); - case '/': - return new Operation( - new Operation( - new Operation(this.leftHand, '*', this.rightHand.derivate(variable)), - '-', - new Operation(this.leftHand.derivate(variable), '*', this.rightHand), - ), - '/', - new Operation(this.rightHand, '^', new NumberElement(2)) - ); - case '^': - case '%': - return new FunctionElement("derivate", this.toEditableString()); - default: - throw new EvalError("Unknown operator " + ope + "."); - } - } - - integrate(variable) { - switch(this.ope) { - case '-': - case '+': - return new Operation(this.leftHand.integrate(variable), this.ope, this.rightHand.integrate(variable)); - case '*': - return new Operation( - new Operation(this.leftHand.derivate(variable), '*', this.rightHand), - '+', - new Operation(this.leftHand, '*', this.rightHand.derivate(variable)) - ); - case '/': - return new Operation( - new Operation(this.leftHand.derivate(variable), '*', this.rightHand), - '+', - new Operation(this.leftHand, '*', this.rightHand.derivate(variable)) - ); - case '^': - case '%': - return new FunctionElement("integrate", this.toEditableString()); - default: - throw new EvalError("Unknown operator " + ope + "."); - } - } - - toEditableString() { - let leftString = this.leftHand.toEditableString(); - let rightString = this.rightHand.toEditableString(); - if(this.leftHand.type == ASEType.OPERATION && OPERATION_PRIORITY[this.ope] > OPERATION_PRIORITY[this.leftHand.ope]) - leftString = "(" + leftString + ")" - if(this.rightHand.type == ASEType.OPERATION && OPERATION_PRIORITY[this.ope] > OPERATION_PRIORITY[this.rightHand.ope]) - rightString = "(" + rightString + ")" - return leftString + " " + this.ope + " " + rightString; - } - - - toLatex() { - switch(this.ope) { - case '-': - case '+': - return this.leftHand.toLatex() + this.ope + this.rightHand.toLatex(); - case '*': - return this.leftHand.toLatex() + " \\times " + this.rightHand.toLatex(); - case '%': - return this.leftHand.toLatex() + " \\mathrm{mod} " + this.rightHand.toLatex(); - case '/': - return "\\frac{" + this.leftHand.toLatex() + "}{" + this.rightHand.toLatex() + "}" - case '^': - return this.leftHand.toLatex() + "^{" + this.rightHand.toLatex() + "}"; - default: - throw new EvalError("Unknown operator " + ope + "."); - } - return this.leftHand.toLatex() + ope + this.rightHand.toLatex(); - } - - isConstant() { - return this.leftHand.isConstant() && this.rightHand.isConstant(); - } -} - -function simplifyFraction(num,den) { - // More than gcd because it allows decimals fractions. - let mult = 1; - if(num%1 != 0) - mult = Math.max(mult,Math.pow(10,num.toString().split('.')[1].length)) - else if(den%1 != 0) - mult = Math.max(mult,Math.pow(10,den.toString().split('.')[1].length)) - let a = Math.abs(num*mult); - let b = Math.abs(den*mult); - let gcd = 0 - if (b > a) {let temp = a; a = b; b = temp;} - while (gcd == 0) { - if (b == 0) gcd = a; - a %= b; - if (a == 0) gcd = b; - b %= a; - } - return [num*mult/gcd, den*mult/gcd] -} - -class Negation extends AbstractSyntaxElement { - type = ASEType.NEGATION; - - constructor(variableName) { - this.varName = variableName; - } - - execute(variables) { - if(variables.includes(this.varName)) { - return variables[this.varName]; - } else { - throw new EvalError("Unknown variable " + this.varName + "."); - } - } - - derivate(variable) { - if(variable == this.varName) - return new NumberElement(1); - return this; - } - - integrate(variable) { - if(variable == this.varName) - // ^2/2 - return new Operation(new Operation(this, '^', new NumberElement(2)), '/', new NumberElement(2)); - return this; - } - - toEditableString() { - return this.varName; - } - - toLatex() { - return this.varName; - } - - isConstant() { - return false; - } -} - -class Negation extends AbstractSyntaxElement { - type = ASEType.NEGATION; - - constructor(expression) { - this.expression = expression; - } - - execute(variables) { - if(variables.includes(this.arrayName)) { - let index = this.astIndex.execute(variables) - if(index % 1 != 0 || index < 0) { // Float index. - throw new EvalError("Non-integer array index " + index + " used as array index for " + this.varName + "."); - } else if(variables[this.arrayName].length <= index) { - throw new EvalError("Out-of-range index " + index + " used as array index for " + this.varName + "."); - } else { - return variables[this.arrayName][index]; - } - } else { - throw new EvalError("Unknown variable " + this.varName + "."); - } - - toLatex() { - return this.varName; - } - } - - simplify() { - return new Negation(this.expression.simplify()); - } - - derivate(variable) { - return new Negation(this.expression.derivate(variable)); - } - - integrate(variable) { - return new Negation(this.expression.integrate(variable)); - } - - toLatex() { - return '-' + this.expression.toLatex(); - } - - isConstant() { - return this.expression.isConstant(); - } -} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js deleted file mode 100644 index a165b69..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/builder.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -.pragma library - -.import "ast.js" as AST -.import "tokenizer.js" as TK - - -class ExpressionBuilder { - constructor(tokenizer) { - this.tokenizer = tokenizer; - } - - parseExpression(delimitors = '') { - // Parse a sequence of operations, and orders them based on OPERATION_PRIORITY. - let elements = [] - let operators = [] - let firstToken = this.tokenizer.peek(); - if(firstToken.type == TK.TokenType.OPERATOR) // First operations. - if(firstToken.value == "-") { - // TODO: Set initial argument. - this.tokenizer.skip(TK.TokenType.OPERATOR) - } else - tokenizer.input.raise(`Invalid operator ${firstToken.value} at begining of statement.`) - else { - - } - } - - parseOperation()` -} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js index 5cf9f9b..e1c4019 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js @@ -28,4 +28,6 @@ var Token = TK.Token var Tokenizer = TK.ExpressionTokenizer var FUNCTIONS_LIST = Reference.FUNCTIONS_LIST +var FUNCTIONS = Reference.FUNCTIONS var CONSTANTS_LIST = Reference.CONSTANTS_LIST +var CONSTANTS = Reference.CONSTANTS From 3f1d089a7810d8703c25463ea5179f74f8850ca6 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 9 Oct 2023 23:28:29 +0200 Subject: [PATCH 156/436] Minor modifications, adding usage to derivative. --- .../Setting/ExpressionEditor.qml | 2 +- .../ad5001/LogarithmPlotter/js/expr-eval.js | 2 +- .../ad5001/LogarithmPlotter/js/math/common.js | 2 ++ .../LogarithmPlotter/js/parsing/reference.js | 20 +------------------ 4 files changed, 5 insertions(+), 21 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 5a758b5..6315e3d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -433,7 +433,7 @@ Item { itemSelected: parent.itemSelected categoryItems: Parsing.CONSTANTS_LIST autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': '', + 'text': item, 'annotation': Parsing.CONSTANTS[item], 'autocomplete': item + " ", 'cursorFinalOffset': 0 }} baseText: parent.visible ? parent.currentToken.value : "" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index ae689e8..4bd6ccd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -27,7 +27,7 @@ var ADDITIONAL_VARCHARS = [ "ₜ","¹","²","³","⁴","⁵","⁶", "⁷","⁸","⁹","⁰","₁","₂","₃", "₄","₅","₆","₇","₈","₉","₀", - "∞" + "∞","π" ] function Instruction(type, value) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 297887b..7eeeb6b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -55,6 +55,8 @@ parser.functions.integral = function(a, b, f, variable) { } parser.functions.derivative = function(f, variable, x) { + if(f == null || variable == null || x == null) + throw EvalError("Usage: derivative(, , )") f = parser.parse(f).toJSFunction(variable, currentVars) return (f(x+DERIVATION_PRECISION/2)-f(x-DERIVATION_PRECISION/2))/DERIVATION_PRECISION } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js index ddc3bdd..92baff9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js @@ -95,23 +95,5 @@ const FUNCTIONS = { 'derivative': () => 0, } const FUNCTIONS_LIST = Object.keys(FUNCTIONS); -// TODO: Complete -const DERIVATIVES = { - "abs": "abs(<1>)/<1>", - "acos": "-derivate(<1>)/sqrt(1-(<1>)^2)", - "acosh": "derivate(<1>)/sqrt((<1>)^2-1)", - "asin": "derivate(<1>)/sqrt(1-(<1>)^2)", - "asinh": "derivate(<1>)/sqrt((<1>)^2+1)", - "atan": "derivate(<1>)/(1+(<1>)^2)", - "atan2": "", -} -const INTEGRALS = { - "abs": "integrate(<1>)*sign(<1>)", - "acos": "", - "acosh": "", - "asin": "", - "asinh": "", - "atan": "", - "atan2": "", -} + From ed4d30573cd73d1f484174530a2ad721319a86b8 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 10 Oct 2023 00:05:19 +0200 Subject: [PATCH 157/436] Adding usage for functions. --- .../LogarithmPlotter/js/parsing/reference.js | 85 +++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js index 92baff9..31a5963 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js @@ -85,15 +85,90 @@ const FUNCTIONS = { 'gamma': Polyfill.gamma, 'Γ': Polyfill.gamma, 'roundTo': (x, exp) => Number(x).toFixed(exp), - 'map': Polyfill.arrayMap, - 'fold': Polyfill.arrayFold, - 'filter': Polyfill.arrayFilter, - 'indexOf': Polyfill.indexOf, - 'join': Polyfill.arrayJoin, + // 'map': Polyfill.arrayMap, + // 'fold': Polyfill.arrayFold, + // 'filter': Polyfill.arrayFilter, + // 'indexOf': Polyfill.indexOf, + // 'join': Polyfill.arrayJoin, // Integral & derivative (only here for autocomplete). 'integral': () => 0, // TODO: Implement 'derivative': () => 0, } const FUNCTIONS_LIST = Object.keys(FUNCTIONS); +class P { + // Parameter class. + constructor(type, name = '', optional = false, multipleAllowed = false) { + this.name = name + this.type = type + this.optional = optional + this.multipleAllowed = multipleAllowed + } + + toString() { + base_string = this.type + if(this.name != '') + base_string = `${this.name}: ${base_string}` + if(this.multipleAllowed) + base_string += '...' + if(!this.optional) + base_string = `<${base_string}>` + else + base_string = `[${base_string}]` + return base_string + } +} + +let string = new P('string') +let bool = new P('boolean') +let number = new P('number') +let array = new P('array') + +const FUNCTIONS_USAGE = { + 'length': [string], + 'not': [bool], + // Math functions + 'abs': [number], + 'acos': [number], + 'acosh': [number], + 'asin': [number], + 'asinh': [number], + 'atan': [number], + 'atan2': [number], + 'atanh': [number], + 'cbrt': [number], + 'ceil': [number], + //'clz32': [number], + 'cos': [number], + 'cosh': [number], + 'exp': [number], + 'expm1': [number], + 'floor': [number], + //'fround': [number], + 'hypot': [number], + //'imul': [number], + 'lg': [number], + 'ln': [number], + 'log': [number], + 'log10': [number], + 'log1p': [number], + 'log2': [number], + 'max': [number, number, new P('number', '', true, null, true)], + 'min': [number, number, new P('number', '', true, null, true)], + 'pow': [number, new P('number', 'exponent')], + 'random': [number, number], + 'round': [number], + 'sign': [number], + 'sin': [number], + 'sinh': [number], + 'sqrt': [number], + 'tan': [number], + 'tanh': [number], + 'trunc': [number], + // Functions in expr-eval, ported here. + 'fac': [number], + 'gamma': [number], + 'Γ': [number], + 'roundTo': [number, new P('number')], +} From d991deee7b6df93da2fa83f02c51ec8b4e7cf1be Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 10 Oct 2023 00:53:35 +0200 Subject: [PATCH 158/436] Reworking the derivative function, removed assignement in parser. The new derivative now supports executable elements. --- .../ObjectLists/ObjectCreationGrid.qml | 1 - .../ad5001/LogarithmPlotter/js/expr-eval.js | 33 +------------------ .../ad5001/LogarithmPlotter/js/math/common.js | 29 ++++++++++++---- .../ad5001/LogarithmPlotter/js/math/latex.js | 6 +++- 4 files changed, 28 insertions(+), 41 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 0c632e7..cf129af 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -42,7 +42,6 @@ Column { */ function openEditorDialog(obj) { // Open editor - console.log(obj, obj.prototype) objectEditor.obj = obj objectEditor.objType = obj.type objectEditor.objIndex = Objects.currentObjects[obj.type].indexOf(obj) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js index 4bd6ccd..1afd66b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js @@ -1117,7 +1117,7 @@ ParserState.prototype.parseExpression = function (instr) { if (this.parseUntilEndStatement(instr, exprInstr)) { return; } - this.parseVariableAssignmentExpression(exprInstr); + this.parseConditionalExpression(exprInstr); if (this.parseUntilEndStatement(instr, exprInstr)) { return; } @@ -1157,37 +1157,6 @@ ParserState.prototype.parseArrayList = function (instr) { return argCount; }; -ParserState.prototype.parseVariableAssignmentExpression = function (instr) { - this.parseConditionalExpression(instr); - while (this.accept(TOP, '=')) { - var varName = instr.pop(); - var varValue = []; - var lastInstrIndex = instr.length - 1; - if (varName.type === IFUNCALL) { - if (!this.tokens.isOperatorEnabled('()=')) { - throw new Error(qsTranslate('error', 'Function definition is not permitted.')); - } - for (var i = 0, len = varName.value + 1; i < len; i++) { - var index = lastInstrIndex - i; - if (instr[index].type === IVAR) { - instr[index] = new Instruction(IVARNAME, instr[index].value); - } - } - this.parseVariableAssignmentExpression(varValue); - instr.push(new Instruction(IEXPR, varValue)); - instr.push(new Instruction(IFUNDEF, varName.value)); - continue; - } - if (varName.type !== IVAR && varName.type !== IMEMBER) { - throw new Error(qsTranslate('error', 'Expected variable for assignment.')); - } - this.parseVariableAssignmentExpression(varValue); - instr.push(new Instruction(IVARNAME, varName.value)); - instr.push(new Instruction(IEXPR, varValue)); - instr.push(binaryInstruction('=')); - } -}; - ParserState.prototype.parseConditionalExpression = function (instr) { this.parseOrExpression(instr); while (this.accept(TOP, '?')) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 7eeeb6b..9aabfd7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -22,8 +22,6 @@ .import "../utils.js" as Utils .import "latex.js" as Latex -const DERIVATION_PRECISION = 0.1 - var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually "pi": Math.PI, "PI": Math.PI, @@ -54,10 +52,27 @@ parser.functions.integral = function(a, b, f, variable) { return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) } -parser.functions.derivative = function(f, variable, x) { - if(f == null || variable == null || x == null) - throw EvalError("Usage: derivative(, , )") - f = parser.parse(f).toJSFunction(variable, currentVars) - return (f(x+DERIVATION_PRECISION/2)-f(x-DERIVATION_PRECISION/2))/DERIVATION_PRECISION +parser.functions.derivative = function(...args) { + let f, target, variable, x + if(args.length == 2) { + [f, x] = args + if(typeof f != 'object' || !f.execute) + throw EvalError(qsTranslate('usage', 'Usage: %1') + .arg(qsTranslate('usage', 'derivative(, )'))) + target = f + f = (x) => target.execute(x) + } else if(args.length == 3) { + [f, variable, x] = args + if(typeof f != 'string') + throw EvalError(qsTranslate('usage', 'Usage: %1') + .arg(qsTranslate('usage', 'derivative(, , )'))) + f = parser.parse(f).toJSFunction(variable, currentVars) + } else + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2') + .arg(qsTranslate('usage', 'derivative(, , )') + .arg(qsTranslate('usage', 'derivative(, , )')))) + + let derivative_precision = x/10 + return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index b52a19e..4f25651 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -71,9 +71,13 @@ function parif(elem, contents) { * @returns {string} */ function functionToLatex(f, args) { + console.log("Generating latex", f, args) switch(f) { case "derivative": - return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; + if(args.length == 3) + return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; + else + return '\\frac{d' + args[0] + '}{dx}'; break; case "integral": return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); From 803416d08de0ee559aa3ab7a286c45c700cddf1e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 10 Oct 2023 01:33:57 +0200 Subject: [PATCH 159/436] New system for integrals the same as for derivatives. --- .../ad5001/LogarithmPlotter/js/math/common.js | 63 ++++++++++++------- .../ad5001/LogarithmPlotter/js/math/latex.js | 8 ++- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 9aabfd7..86d16e6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -44,34 +44,55 @@ const parser = new ExprEval.Parser() parser.consts = Object.assign({}, parser.consts, evalVariables) +/** + * Parses arguments for a function, returns the corresponding JS function if it exists. + * Throws either usage error otherwise. + * @param {array} args - Arguments of the function, either [ ExecutableObject ] or [ string, variable ]. + * @param {string} usage1 - Usage for executable object. + * @param {string} usage2 - Usage for string function. + * @return {callable} JS function to call.. + */ +function parseArgumentsForFunction(args, usage1, usage2) { + let f, target, variable + if(args.length == 1) { + // Parse object + f = args[0] + if(typeof f != 'object' || !f.execute) + throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage1)) + let target = f + f = (x) => target.execute(x) + } else if(args.length == 2) { + // Parse variable + [f,variable] = args + if(typeof f != 'string' || typeof variable != 'number') + throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2)) + f = parser.parse(f).toJSFunction(variable, currentVars) + } else + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2))) + return f +} + // Function definition -parser.functions.integral = function(a, b, f, variable) { +parser.functions.integral = function(a, b, ...args) { + let usage1 = qsTranslate('usage', 'integral(, , )') + let usage2 = qsTranslate('usage', 'integral(, , , )') + let f = parseArgumentsForFunction(args, usage1, usage2) + if(a == null || b == null) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2))) + // https://en.wikipedia.org/wiki/Simpson%27s_rule // Simpler, faster than tokenizing the expression - f = parser.parse(f).toJSFunction(variable, currentVars) return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) } parser.functions.derivative = function(...args) { - let f, target, variable, x - if(args.length == 2) { - [f, x] = args - if(typeof f != 'object' || !f.execute) - throw EvalError(qsTranslate('usage', 'Usage: %1') - .arg(qsTranslate('usage', 'derivative(, )'))) - target = f - f = (x) => target.execute(x) - } else if(args.length == 3) { - [f, variable, x] = args - if(typeof f != 'string') - throw EvalError(qsTranslate('usage', 'Usage: %1') - .arg(qsTranslate('usage', 'derivative(, , )'))) - f = parser.parse(f).toJSFunction(variable, currentVars) - } else - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2') - .arg(qsTranslate('usage', 'derivative(, , )') - .arg(qsTranslate('usage', 'derivative(, , )')))) - + let usage1 = qsTranslate('usage', 'derivative(, )') + let usage2 = qsTranslate('usage', 'derivative(, , )') + let x = args.pop() + let f = parseArgumentsForFunction(args, usage1, usage2) + if(x == null) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2))) + let derivative_precision = x/10 return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 4f25651..1e84912 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -71,16 +71,18 @@ function parif(elem, contents) { * @returns {string} */ function functionToLatex(f, args) { - console.log("Generating latex", f, args) switch(f) { case "derivative": if(args.length == 3) return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; else - return '\\frac{d' + args[0] + '}{dx}'; + return '\\frac{d' + args[0] + '}{dx}(x)'; break; case "integral": - return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); + if(args.length == 4) + return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); + else + return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2] + '(t) dt'; break; case "sqrt": return '\\sqrt\\left(' + args.join(', ') + '\\right)'; From bf211df67dee9576c33ac60eb541966524dbc041 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 10 Oct 2023 01:58:55 +0200 Subject: [PATCH 160/436] Adding function usage to auto complete. --- .../Setting/AutocompletionCategory.qml | 2 ++ .../LogarithmPlotter/Setting/ExpressionEditor.qml | 2 +- .../eu/ad5001/LogarithmPlotter/js/math/common.js | 10 +++++----- .../ad5001/LogarithmPlotter/js/parsing/parsing.js | 1 + .../ad5001/LogarithmPlotter/js/parsing/reference.js | 13 ++++++++----- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index d5cc9af..cf42238 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -113,9 +113,11 @@ ListView { Text { id: annotationText anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter topPadding: 2 bottomPadding: 2 rightPadding: 15 + font.pixelSize: autocompleteText.font.pixelSize - 2 text: listFiltered.model[index].annotation color: parent.selected ? sysPaletteIn.highlightedText : sysPaletteIn.windowText } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index 6315e3d..bde4962 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -448,7 +448,7 @@ Item { itemSelected: parent.itemSelected categoryItems: Parsing.FUNCTIONS_LIST autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': '', + 'text': item, 'annotation': Parsing.FUNCTIONS_USAGE[item].join(', '), 'autocomplete': item+'()', 'cursorFinalOffset': -1 }} baseText: parent.visible ? parent.currentToken.value : "" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 86d16e6..450ae6d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -68,7 +68,7 @@ function parseArgumentsForFunction(args, usage1, usage2) { throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2)) f = parser.parse(f).toJSFunction(variable, currentVars) } else - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2))) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) return f } @@ -78,7 +78,7 @@ parser.functions.integral = function(a, b, ...args) { let usage2 = qsTranslate('usage', 'integral(, , , )') let f = parseArgumentsForFunction(args, usage1, usage2) if(a == null || b == null) - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2))) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) // https://en.wikipedia.org/wiki/Simpson%27s_rule // Simpler, faster than tokenizing the expression @@ -86,12 +86,12 @@ parser.functions.integral = function(a, b, ...args) { } parser.functions.derivative = function(...args) { - let usage1 = qsTranslate('usage', 'derivative(, )') - let usage2 = qsTranslate('usage', 'derivative(, , )') + let usage1 = qsTranslate('usage', 'derivative(, )') + let usage2 = qsTranslate('usage', 'derivative(, , )') let x = args.pop() let f = parseArgumentsForFunction(args, usage1, usage2) if(x == null) - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2))) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) let derivative_precision = x/10 return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js index e1c4019..a7d5d48 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js @@ -29,5 +29,6 @@ var Tokenizer = TK.ExpressionTokenizer var FUNCTIONS_LIST = Reference.FUNCTIONS_LIST var FUNCTIONS = Reference.FUNCTIONS +var FUNCTIONS_USAGE = Reference.FUNCTIONS_USAGE var CONSTANTS_LIST = Reference.CONSTANTS_LIST var CONSTANTS = Reference.CONSTANTS diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js index 31a5963..36d4111 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js @@ -106,7 +106,7 @@ class P { } toString() { - base_string = this.type + let base_string = this.type if(this.name != '') base_string = `${this.name}: ${base_string}` if(this.multipleAllowed) @@ -120,7 +120,7 @@ class P { } let string = new P('string') -let bool = new P('boolean') +let bool = new P('bool') let number = new P('number') let array = new P('array') @@ -153,9 +153,9 @@ const FUNCTIONS_USAGE = { 'log10': [number], 'log1p': [number], 'log2': [number], - 'max': [number, number, new P('number', '', true, null, true)], - 'min': [number, number, new P('number', '', true, null, true)], - 'pow': [number, new P('number', 'exponent')], + 'max': [number, number, new P('numbers', '', true, true)], + 'min': [number, number, new P('numbers', '', true, true)], + 'pow': [number, new P('number', 'exp')], 'random': [number, number], 'round': [number], 'sign': [number], @@ -170,5 +170,8 @@ const FUNCTIONS_USAGE = { 'gamma': [number], 'Γ': [number], 'roundTo': [number, new P('number')], + // Function manipulation + 'derivative': [new P('f'), new P('string', 'var', true), number], + 'integral': [new P('from'), new P('to'), new P('f'), new P('string', 'var', true)], } From 22106f97b53e134ad2c1fc2d21befa24c5e7173e Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 10 Oct 2023 02:13:17 +0200 Subject: [PATCH 161/436] Adding new strings --- LogarithmPlotter/i18n/lp_de.ts | 247 +++++++++++++++----------- LogarithmPlotter/i18n/lp_en.ts | 247 +++++++++++++++----------- LogarithmPlotter/i18n/lp_es.ts | 251 +++++++++++++++------------ LogarithmPlotter/i18n/lp_fr.ts | 247 +++++++++++++++----------- LogarithmPlotter/i18n/lp_hu.ts | 247 +++++++++++++++----------- LogarithmPlotter/i18n/lp_nb_NO.ts | 251 +++++++++++++++------------ LogarithmPlotter/i18n/lp_template.ts | 251 +++++++++++++++------------ 7 files changed, 981 insertions(+), 760 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index c72a28e..13c83d9 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Über LogarithmPlotter @@ -189,12 +189,12 @@ Changelog - + Fetching changelog... Changelog abrufen… - + Done Schließen @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -236,22 +236,22 @@ Name - + Label content Etikett - + null leer - + name Name - + name + value Name + Wert @@ -411,17 +411,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Filtern… - + Redo > Wiederherstellen > - + > Now > Aktueller Stand - + < Undo < Rückgängig @@ -452,47 +452,47 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not save file: Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -500,7 +500,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ObjectCreationGrid - + + Create new: + Neu erstellen: @@ -569,7 +569,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" PickLocationOverlay - + Pointer precision: Genauigkeit des Zeigers: @@ -578,32 +578,32 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Am Gitter einrasten - + Snap to grid: Am Raster einrasten: - + Pick X X nehmen - + Pick Y Y nehmen - + Open picker settings Zeigereinstellungen öffnen - + Hide picker settings Zeigereinstellungen ausblenden - + (no pick selected) (keine Auswahl ausgewählt) @@ -641,67 +641,67 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Minimum Y - + X Axis Step X-Achsen-Schritt - + Y Axis Step Y-Achsen-Schritt - + Line width Linienbreite - + Text size (px) Textgröße (px) - + X Label Etikett der X-Achse - + Y Label Etikett der Y-Achse - + X Log scale Logarithmische Skala in X - + Show X graduation X-Teilung anzeigen - + Show Y graduation Y-Teilung anzeigen - + Copy to clipboard Kopieren in die Zwischenablage - + Save plot Grafik speichern - + Save plot as Grafik speichern unter - + Load plot Grafik laden @@ -714,87 +714,87 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Danksagungen und Beiträge - LogarithmPlotter - + Source code Quellcode - + Original library by Raphael Graf Originalbibliothek von Raphael Graf - + Source Quelle - + Ported to Javascript by Matthew Crumley Portiert auf Javascript von Matthew Crumley - - - - - + + + + + Website Website - + Ported to QMLJS by Ad5001 Portiert auf QMLJS von Ad5001 - + Libraries included Einschließlich Bibliotheken - + Email E-Mail - + English Englisch - + French Französisch - + German Deutsch - + Hungarian Ungarisch - - + + Github Github - + Norwegian Norwegisch - + Translations included Einschließlich Übersetzungen - + Improve Verbessern @@ -856,7 +856,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - + %1: %1: @@ -895,178 +895,176 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - - + + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. - + Undefined variable %1. Die Variable %1 ist nicht definiert. - + In order to be executed, object %1 must have at least one argument. Um als Funktion verwendet zu werden, benötigt das Objekt %1 mindestens ein Parameter. - + %1 cannot be executed. %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). - + Unknown character "%1". Unbekanntes Schriftzeichen "%1". - - + + Illegal escape sequence: %1. Unzulässige Escapesequenz: %1. - - + + Parse error [%1:%2]: %3 Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 - Function definition is not permitted. - Funktionsdefinition ist nicht erlaubt. + Funktionsdefinition ist nicht erlaubt. - Expected variable for assignment. - Erwartete Variable für Zuweisung. + Erwartete Variable für Zuweisung. - + Unexpected ".": member access is not permitted Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt - + Unexpected "[]": arrays are disabled. Unerwartetes "[]": Arrays sind deaktiviert. - + Unexpected symbol: %1. Unerwartetes Symbol: %1. - - + + Function %1 must have at least one argument. Die Funktion %1 benötigt mindestens ein Parameter. - + First argument to map is not a function. Der erste Parameter von map ist keine Formel. - + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. - + Error while parsing expression for property %1: %2 @@ -1091,7 +1089,7 @@ Die letzte Änderung wurde rückgängig gemacht. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler @@ -1625,6 +1623,43 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Es konnten keine Aktualisierungsinformationen abgerufen werden:{}. + + usage + + + + Usage: %1 + + + + + + + Usage: %1 or +%2 + + + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + + derivative(<f: ExecutableObject>, <x: number>) + + + + + derivative(<f: string>, <variable: string>, <x: number>) + + + visibility diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index d472569..e3847cf 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter About LogarithmPlotter @@ -189,12 +189,12 @@ Changelog - + Fetching changelog... Fetching changelog… - + Done Done @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -236,22 +236,22 @@ Name - + Label content Label content - + null null - + name name - + name + value name + value @@ -411,17 +411,17 @@ These settings can be changed at any time from the "Settings" menu.Filter… - + Redo > Redo > - + > Now > Now - + < Undo < Undo @@ -452,47 +452,47 @@ These settings can be changed at any time from the "Settings" menu.History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not save file: Could not save file: - + Loaded file '%1'. Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -500,7 +500,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: + Create new: @@ -569,7 +569,7 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: Pointer precision: @@ -578,32 +578,32 @@ These settings can be changed at any time from the "Settings" menu.Snap to grid - + Snap to grid: Snap to grid: - + Pick X Pick X - + Pick Y Pick Y - + Open picker settings Open picker settings - + Hide picker settings Hide picker settings - + (no pick selected) (no pick selected) @@ -641,67 +641,67 @@ These settings can be changed at any time from the "Settings" menu.Min Y - + X Axis Step X Axis Step - + Y Axis Step Y Axis Step - + Line width Line width - + Text size (px) Text size (px) - + X Label X Label - + Y Label Y Label - + X Log scale X Log scale - + Show X graduation Show X graduation - + Show Y graduation Show Y graduation - + Copy to clipboard Copy to clipboard - + Save plot Save plot - + Save plot as Save plot as - + Load plot Open plot @@ -714,87 +714,87 @@ These settings can be changed at any time from the "Settings" menu.Thanks and Contributions - LogarithmPlotter - + Source code Source code - + Original library by Raphael Graf Original library by Raphael Graf - + Source Source - + Ported to Javascript by Matthew Crumley Ported to Javascript by Matthew Crumley - - - - - + + + + + Website Website - + Ported to QMLJS by Ad5001 Ported to QMLJS by Ad5001 - + Libraries included Libraries included - + Email Email - + English English - + French French - + German German - + Hungarian Hungarian - - + + Github Github - + Norwegian Norwegian - + Translations included Translations included - + Improve Improve @@ -856,7 +856,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: %1: @@ -895,178 +895,176 @@ These settings can be changed at any time from the "Settings" menu. error - - + + Cannot find property %1 of object %2. Cannot find property %1 of object %2. - + Undefined variable %1. Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. %1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). - + Unknown character "%1". Unknown character "%1". - - + + Illegal escape sequence: %1. Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 Parse error [%1:%2]: %3 - + Expected %1 Expected %1 - + Unexpected %1 Unexpected %1 - Function definition is not permitted. - Function definition is not permitted. + Function definition is not permitted. - Expected variable for assignment. - Expected variable for assignment. + Expected variable for assignment. - + Unexpected ".": member access is not permitted Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. Unexpected symbol: %1. - - + + Function %1 must have at least one argument. Function %1 must have at least one argument. - + First argument to map is not a function. First argument to map is not a function. - + Second argument to map is not an array. Second argument to map is not an array. - + First argument to fold is not a function. First argument to fold is not a function. - + Second argument to fold is not an array. Second argument to fold is not an array. - + First argument to filter is not a function. First argument to filter is not a function. - + Second argument to filter is not an array. Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - + Second argument to join is not an array. Second argument to join is not an array. - + EOF End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1091,7 +1089,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error @@ -1625,6 +1623,43 @@ Please make sure your LaTeX installation is correct and report a bug if so.Could not fetch update information: {}. + + usage + + + + Usage: %1 + + + + + + + Usage: %1 or +%2 + + + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + + derivative(<f: ExecutableObject>, <x: number>) + + + + + derivative(<f: string>, <variable: string>, <x: number>) + + + visibility diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 8f4f452..11bbbc5 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter @@ -189,12 +189,12 @@ Changelog - + Fetching changelog... - + Done @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -236,22 +236,22 @@ - + Label content - + null - + name - + name + value @@ -379,17 +379,17 @@ These settings can be changed at any time from the "Settings" menu. - + Redo > - + > Now - + < Undo @@ -420,47 +420,47 @@ These settings can be changed at any time from the "Settings" menu. - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -468,7 +468,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: @@ -517,37 +517,37 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -585,67 +585,67 @@ These settings can be changed at any time from the "Settings" menu. - + X Axis Step - + Y Axis Step - + Line width - + Text size (px) - + X Label - + Y Label - + X Log scale - + Show X graduation - + Show Y graduation - + Copy to clipboard - + Save plot - + Save plot as - + Load plot @@ -658,87 +658,87 @@ These settings can be changed at any time from the "Settings" menu. - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + Github - + Norwegian - + Translations included - + Improve @@ -800,7 +800,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -839,178 +839,168 @@ These settings can be changed at any time from the "Settings" menu. error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - - Function definition is not permitted. - - - - - Expected variable for assignment. - - - - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1029,7 +1019,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -1520,6 +1510,43 @@ Please make sure your latex installation is correct and report a bug if so. + + usage + + + + Usage: %1 + + + + + + + Usage: %1 or +%2 + + + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + + derivative(<f: ExecutableObject>, <x: number>) + + + + + derivative(<f: string>, <variable: string>, <x: number>) + + + visibility diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index e6aea4b..b666c0c 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter @@ -190,12 +190,12 @@ Changelog - + Fetching changelog... Récupération de l'historique des modifications… - + Done Fermer @@ -203,13 +203,13 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -237,22 +237,22 @@ Nom - + Label content Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -419,17 +419,17 @@ These settings can always be changed at any time from the "Settings" m Filtrer… - + Redo > Rétablir > - + > Now > État actuel - + < Undo < Annuler @@ -460,47 +460,47 @@ These settings can always be changed at any time from the "Settings" m Historique - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not save file: Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -508,7 +508,7 @@ These settings can always be changed at any time from the "Settings" m ObjectCreationGrid - + + Create new: + Créer : @@ -577,7 +577,7 @@ These settings can always be changed at any time from the "Settings" m PickLocationOverlay - + Pointer precision: Précision du pointeur : @@ -586,32 +586,32 @@ These settings can always be changed at any time from the "Settings" m Placement sur la grille - + Snap to grid: Aligner sur la grille : - + Pick X Prendre la position X - + Pick Y Prendre la position Y - + Open picker settings Ouvrir les paramètres du pointeur - + Hide picker settings Cacher les paramètres du pointeur - + (no pick selected) (aucun axe sélectionné) @@ -649,67 +649,67 @@ These settings can always be changed at any time from the "Settings" m Min Y - + X Axis Step Pas de l'axe X - + Y Axis Step Pas de l'axe Y - + Line width Taille des lignes - + Text size (px) Taille du texte (px) - + X Label Label de l'axe X - + Y Label Label de l'axe Y - + X Log scale Échelle logarithmique en X - + Show X graduation Montrer la graduation de l'axe X - + Show Y graduation Montrer la graduation de l'axe Y - + Copy to clipboard Copier vers le presse-papiers - + Save plot Sauvegarder le graphe - + Save plot as Sauvegarder le graphe sous - + Load plot Ouvrir un graphe @@ -722,87 +722,87 @@ These settings can always be changed at any time from the "Settings" m Remerciements et contributions - LogarithmPlotter - + Source code Code source - + Original library by Raphael Graf Bibliothèque originale de Raphael Graf - + Source Source - + Ported to Javascript by Matthew Crumley Porté en Javascript par Matthew Crumley - - - - - + + + + + Website Site web - + Ported to QMLJS by Ad5001 Porté à QMLJS par Ad5001 - + Libraries included Bibliothèques incluses - + Email Email - + English Anglais - + French Français - + German Allemand - + Hungarian Hongrois - - + + Github Github - + Norwegian Norvégien - + Translations included Traductions incluses - + Improve Améliorer @@ -865,7 +865,7 @@ These settings can always be changed at any time from the "Settings" m - + %1: %1 : @@ -904,178 +904,176 @@ These settings can always be changed at any time from the "Settings" m error - - + + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. - + Undefined variable %1. La variable %1 n'est pas définie. - + In order to be executed, object %1 must have at least one argument. Pour être utilisé comme fonction, l'objet %1 nécessite au moins un argument. - + %1 cannot be executed. %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). - + Unknown character "%1". Le caractère "%1" est inconnu. - - + + Illegal escape sequence: %1. Séquence d'échappement illégale : %1. - - + + Parse error [%1:%2]: %3 Erreur de syntaxe [%1:%2] : %3 - + Expected %1 %1 attendu - + Unexpected %1 %1 inattendu - Function definition is not permitted. - La définition de fonctions n'est pas autorisée. + La définition de fonctions n'est pas autorisée. - Expected variable for assignment. - Une variable est attendue pour l'affectation. + Une variable est attendue pour l'affectation. - + Unexpected ".": member access is not permitted "." inattendu : l'accès aux propriétés n'est pas autorisé - + Unexpected "[]": arrays are disabled. "[]" inattendu : les tableaux sont désactivés. - + Unexpected symbol: %1. Symbole inconnu : %1. - - + + Function %1 must have at least one argument. La fonction %1 nécessite au moins un argument. - + First argument to map is not a function. Le premier argument de map n'est pas une fonction. - + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. - + Error while parsing expression for property %1: %2 @@ -1100,7 +1098,7 @@ La dernière modification a été annulée. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe @@ -1634,6 +1632,43 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Impossible de récupérer les informations de mise à jour. {}. + + usage + + + + Usage: %1 + + + + + + + Usage: %1 or +%2 + + + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + + derivative(<f: ExecutableObject>, <x: number>) + + + + + derivative(<f: string>, <variable: string>, <x: number>) + + + visibility diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index c43ddc7..28517a4 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye @@ -189,12 +189,12 @@ Changelog - + Fetching changelog... Változásnapló lekérése… - + Done Kész @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -236,22 +236,22 @@ Név - + Label content Címketartalom - + null üres - + name név - + name + value név + érték @@ -411,17 +411,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Szűrő… - + Redo > Ismétlés > - + > Now > Most - + < Undo < Visszavonás @@ -452,47 +452,47 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not save file: A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -500,7 +500,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ObjectCreationGrid - + + Create new: + Új létrehozása: @@ -569,7 +569,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. PickLocationOverlay - + Pointer precision: Mutató pontossága: @@ -578,32 +578,32 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Rácshoz illesztés - + Snap to grid: Rácshoz igazítás: - + Pick X X kijelölése - + Pick Y Y kijelölése - + Open picker settings Kijelölési beállítások megnyitása - + Hide picker settings Kijelölési beállítások elrejtése - + (no pick selected) (nincs kijelölés kiválasztva) @@ -641,67 +641,67 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Legkisebb Y - + X Axis Step X tengely lépésköze - + Y Axis Step Y tengely lépésköze - + Line width Vonalvastagság - + Text size (px) Szövegméret (képpont) - + X Label X címke - + Y Label Y címke - + X Log scale X tengely logaritmikus skálával - + Show X graduation X érettségi megjelenítése - + Show Y graduation Y érettségi megjelenítése - + Copy to clipboard Másolás a vágólapra - + Save plot Ábra mentése - + Save plot as Ábra mentése másként - + Load plot Ábra betöltése @@ -714,87 +714,87 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Köszönet és hozzájárulás - LogarithmPlotter - + Source code Forráskód - + Original library by Raphael Graf Eredeti könyvtár: Graf Raphael - + Source Forrás - + Ported to Javascript by Matthew Crumley JavaScript-átalakítás: Crumley Máté - - - - - + + + + + Website Honlap - + Ported to QMLJS by Ad5001 QMLJS-átalakítás: Ad5001 - + Libraries included Tartalmazott könyvtárak - + Email E-mail - + English angol - + French francia - + German német - + Hungarian magyar - - + + Github GitHub - + Norwegian norvég - + Translations included A felhasználói felület nyelvei - + Improve Fejlesztés @@ -856,7 +856,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + %1: %1: @@ -895,178 +895,176 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - - + + Cannot find property %1 of object %2. A(z) %2 objektum %1 tulajdonsága nem található. - + Undefined variable %1. A(z) %1 változó nincs meghatározva. - + In order to be executed, object %1 must have at least one argument. A végrehajtáshoz a(z) %1 objektumnak legalább egy argumentummal kell rendelkeznie. - + %1 cannot be executed. A(z) %1 nem függvény. - - - + + + Invalid expression. Érvénytelen kifejezés. - + Invalid expression (parity). Érvénytelen kifejezés (paritás). - + Unknown character "%1". Ismeretlen karakter „%1”. - - + + Illegal escape sequence: %1. Érvénytelen kilépési sorozat: %1. - - + + Parse error [%1:%2]: %3 Elemzési hiba [%1:%2]: %3 - + Expected %1 Várható %1 - + Unexpected %1 Váratlan %1 - Function definition is not permitted. - A függvény meghatározása nem engedélyezett. + A függvény meghatározása nem engedélyezett. - Expected variable for assignment. - A hozzárendeléshez várt változó. + A hozzárendeléshez várt változó. - + Unexpected ".": member access is not permitted Váratlan „.”: a tagok hozzáférése nem engedélyezett - + Unexpected "[]": arrays are disabled. Váratlan „[]”: a tömbök le vannak tiltva. - + Unexpected symbol: %1. Váratlan szimbólum: %1. - - + + Function %1 must have at least one argument. A(z) %1 függvénynek legalább egy argumentumnak kell lennie. - + First argument to map is not a function. Az első leképezési argumentum nem függvény. - + Second argument to map is not an array. A második leképezési argumentum nem tömb. - + First argument to fold is not a function. Az első behajtási argumentum nem függvény. - + Second argument to fold is not an array. A második behajtási argumentum nem tömb. - + First argument to filter is not a function. Az első szűrési argumentum nem függvény. - + Second argument to filter is not an array. A második szűrési argumentum nem tömb. - + Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. - + Second argument to join is not an array. A második csatlakozási argumentum nem tömb. - + EOF Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. - + Error while parsing expression for property %1: %2 @@ -1091,7 +1089,7 @@ Az utolsó módosítás visszavonása. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba @@ -1617,6 +1615,43 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Nem sikerült lekérni a frissítési adatokat: {}. + + usage + + + + Usage: %1 + + + + + + + Usage: %1 or +%2 + + + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + + derivative(<f: ExecutableObject>, <x: number>) + + + + + derivative(<f: string>, <variable: string>, <x: number>) + + + visibility diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 4d1cc28..18d0f09 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Om @@ -189,12 +189,12 @@ Changelog - + Fetching changelog... - + Done @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -236,22 +236,22 @@ Navn - + Label content Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -411,17 +411,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Redo > Angre > - + > Now > Nå - + < Undo < Angre @@ -452,47 +452,47 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not save file: Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -500,7 +500,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ObjectCreationGrid - + + Create new: + Opprett ny: @@ -569,7 +569,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. PickLocationOverlay - + Pointer precision: Peker-presisjon: @@ -578,32 +578,32 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Fest til rutenett - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -641,67 +641,67 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Min. Y - + X Axis Step X-aksesteg - + Y Axis Step Y-aksesteg - + Line width Linjebredde - + Text size (px) Tekststørrelse (piksler) - + X Label Navn på X-akse - + Y Label Navn på Y-akse - + X Log scale Logaritmisk skala i x - + Show X graduation Vis X-inndeling - + Show Y graduation Vis Y-inndeling - + Copy to clipboard Kopier til utklippstavle - + Save plot Lagre plott - + Save plot as Lagre plott som - + Load plot Last inn plott @@ -714,87 +714,87 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + Github - + Norwegian - + Translations included - + Improve @@ -856,7 +856,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + %1: @@ -895,178 +895,168 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - - Function definition is not permitted. - - - - - Expected variable for assignment. - - - - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1085,7 +1075,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -1599,6 +1589,43 @@ Please make sure your latex installation is correct and report a bug if so.Kunne ikke hente info om hvorvidt det er nye versjoner: {}. + + usage + + + + Usage: %1 + + + + + + + Usage: %1 or +%2 + + + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + + derivative(<f: ExecutableObject>, <x: number>) + + + + + derivative(<f: string>, <variable: string>, <x: number>) + + + visibility diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 87973c3..2cbbff2 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter @@ -189,12 +189,12 @@ Changelog - + Fetching changelog... - + Done @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -236,22 +236,22 @@ - + Label content - + null - + name - + name + value @@ -379,17 +379,17 @@ These settings can be changed at any time from the "Settings" menu. - + Redo > - + > Now - + < Undo @@ -420,47 +420,47 @@ These settings can be changed at any time from the "Settings" menu. - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -468,7 +468,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: @@ -517,37 +517,37 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -585,67 +585,67 @@ These settings can be changed at any time from the "Settings" menu. - + X Axis Step - + Y Axis Step - + Line width - + Text size (px) - + X Label - + Y Label - + X Log scale - + Show X graduation - + Show Y graduation - + Copy to clipboard - + Save plot - + Save plot as - + Load plot @@ -658,87 +658,87 @@ These settings can be changed at any time from the "Settings" menu. - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - - - - - + + + + + Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - - + + Github - + Norwegian - + Translations included - + Improve @@ -800,7 +800,7 @@ These settings can be changed at any time from the "Settings" menu. - + %1: @@ -839,178 +839,168 @@ These settings can be changed at any time from the "Settings" menu. error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - - Function definition is not permitted. - - - - - Expected variable for assignment. - - - - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1029,7 +1019,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -1520,6 +1510,43 @@ Please make sure your latex installation is correct and report a bug if so. + + usage + + + + Usage: %1 + + + + + + + Usage: %1 or +%2 + + + + + integral(<from: number>, <to: number>, <f: ExecutableObject>) + + + + + integral(<from: number>, <to: number>, <f: string>, <variable: string>) + + + + + derivative(<f: ExecutableObject>, <x: number>) + + + + + derivative(<f: string>, <variable: string>, <x: number>) + + + visibility From b8d679e118dbe964dc17aa39b3926fa818853a32 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 10 Oct 2023 14:28:46 +0000 Subject: [PATCH 162/436] Translated using Weblate (English) Currently translated at 100.0% (271 of 271 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/en/ --- LogarithmPlotter/i18n/lp_en.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index e3847cf..91b0e51 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -1629,7 +1629,7 @@ Please make sure your LaTeX installation is correct and report a bug if so. Usage: %1 - + Usage: %1 @@ -1637,27 +1637,28 @@ Please make sure your LaTeX installation is correct and report a bug if so. Usage: %1 or %2 - + Usage: %1 or +%2 integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) From 5284c71ee7a7fea6c73c089a1c9f92013f049e47 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 10 Oct 2023 14:36:25 +0000 Subject: [PATCH 163/436] Translated using Weblate (French) Currently translated at 100.0% (271 of 271 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/fr/ --- LogarithmPlotter/i18n/lp_fr.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index b666c0c..aeb408f 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -1638,7 +1638,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Usage: %1 - + Emploi : %1 @@ -1646,27 +1646,28 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Usage: %1 or %2 - + Emploi : %1 ou +%2 integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<de : nombre>, <à : nombre>, <f : Objet exécutable>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f : Objet exécutable>, <x : nombre>) derivative(<f: string>, <variable: string>, <x: number>) - + derivative(<f : fonction chaîne>, <variable>, <x : nombre>) From 298acaace26b91c13ba7d0ebb68b3aa94e154e7a Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 18 Oct 2023 16:06:11 +0200 Subject: [PATCH 164/436] Reworking SVG object icons to use default system sans-serif font. Provides better native integration at the cost of uniformisation. --- .../icons/objects/Function.svg | 109 ++++++++---------- .../icons/objects/Gain Bode.svg | 89 +++++++------- .../icons/objects/Phase Bode.svg | 86 +++++++------- .../LogarithmPlotter/icons/objects/Point.svg | 68 ++++++++++- .../icons/objects/Sequence.svg | 102 +++++++--------- .../icons/objects/Somme gains Bode.svg | 96 --------------- .../icons/objects/Somme gains Bode2.svg | 93 --------------- .../icons/objects/Somme phases Bode.svg | 92 --------------- .../LogarithmPlotter/icons/objects/Text.svg | 90 +++++++++++---- .../icons/objects/X Cursor.svg | 95 ++++++++------- 10 files changed, 354 insertions(+), 566 deletions(-) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme gains Bode.svg delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme gains Bode2.svg delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme phases Bode.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Function.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Function.svg index 2dbb7cf..6d707ce 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Function.svg +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Function.svg @@ -1,44 +1,17 @@ + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - @@ -47,8 +20,7 @@ image/svg+xml - - 2021 + 2021-2023 Ad5001 @@ -56,7 +28,7 @@ - (C) Ad5001 2021 - Licensed under CC4.0-BY-NC-SA + (C) Ad5001 2021-2023 - Licensed under CC4.0-BY-NC-SA - - - - - + f + x + ( + ) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Gain Bode.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Gain Bode.svg index 2d085e7..3a2b85f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Gain Bode.svg +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Gain Bode.svg @@ -1,47 +1,17 @@ + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - - @@ -50,13 +20,40 @@ image/svg+xml - + 2021-2023 + + + Ad5001 + + + + + (C) Ad5001 2021-2023 - Licensed under CC4.0-BY-NC-SA + + + + + + + + + + + + ω + x="-0.105" + y="11.959" + style="font-size:17px">ω + d="m 20.686533,-6.169873 2.232051,-0.1339746 -0.06218,13.8923049 -2.23205,0.1339746 z" /> diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Phase Bode.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Phase Bode.svg index e9a0278..9bb60bf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Phase Bode.svg +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Phase Bode.svg @@ -1,44 +1,17 @@ + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - @@ -47,13 +20,40 @@ image/svg+xml - + 2021-2023 + + + Ad5001 + + + + + (C) Ad5001 2021-2023 - Licensed under CC4.0-BY-NC-SA + + + + + + + + + + + + + d="m 15,2 v 14 h 2 V 4 h 7 V 2 Z" /> φ + x="6.1339936" + y="11.163" + style="font-size:17px;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none">φ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Point.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Point.svg index 8bee87b..d8de8b0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Point.svg +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Point.svg @@ -1 +1,67 @@ -A + + + + + A + + + + 2021-2023 + + + Ad5001 + + + + + (C) Ad5001 2021-2023 - Licensed under CC4.0-BY-NC-SA + + + + + + + + + + + + + + + + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Sequence.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Sequence.svg index 9bbbf82..75c08f1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Sequence.svg +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Sequence.svg @@ -1,45 +1,17 @@ + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - @@ -48,56 +20,62 @@ image/svg+xml - + 2021-2023 + + + Ad5001 + + + + + (C) Ad5001 2021-2023 - Licensed under CC4.0-BY-NC-SA + + u + style="font-size:17.3333px;-inkscape-font-specification:sans-serif;font-family:sans-serif;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">u n - - - - - - + style="font-size:17px;stroke-width:1.00003;-inkscape-font-specification:sans-serif;font-family:sans-serif;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal">n + ( + ) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme gains Bode.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme gains Bode.svg deleted file mode 100644 index 4a61e54..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme gains Bode.svg +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme gains Bode2.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme gains Bode2.svg deleted file mode 100644 index 6965e85..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme gains Bode2.svg +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - - ΣG - - - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme phases Bode.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme phases Bode.svg deleted file mode 100644 index 24aa9d0..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Somme phases Bode.svg +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - Σφ - - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Text.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Text.svg index 0872104..0fd08e2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Text.svg +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/Text.svg @@ -1,19 +1,19 @@ + inkscape:version="1.3 (0e150ed6c4, 2023-07-21)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + inkscape:window-maximized="1" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1"> + id="grid2039" + originx="0" + originy="0" + spacingy="1" + spacingx="1" + units="px" + visible="true" /> + id="grid2058" + originx="0" + originy="0" + spacingy="1" + spacingx="1" + units="px" + visible="true" /> @@ -50,8 +65,37 @@ image/svg+xml - + 2021-2023 + + + Ad5001 + + + + + (C) Ad5001 2021-2023 - Licensed under CC4.0-BY-NC-SA + + + + + + + + + + + + - + t diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/X Cursor.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/X Cursor.svg index a7b534d..aeb04c8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/X Cursor.svg +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/objects/X Cursor.svg @@ -1,47 +1,17 @@ + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - - @@ -50,13 +20,40 @@ image/svg+xml - + 2021-2023 + + + Ad5001 + + + + + (C) Ad5001 2021-2023 - Licensed under CC4.0-BY-NC-SA + + + + + + + + + + + + - - + X From 8bb147cbee1bab32cd7cb8e1ccd350319c928d62 Mon Sep 17 00:00:00 2001 From: ovari Date: Wed, 18 Oct 2023 23:35:19 +0000 Subject: [PATCH 165/436] Translated using Weblate (Hungarian) Currently translated at 100.0% (271 of 271 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 28517a4..89396ce 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1621,7 +1621,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Usage: %1 - + Használat: %1 @@ -1629,27 +1629,28 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Usage: %1 or %2 - + Használat: %1 vagy +%2 integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) derivative(<f: ExecutableObject>, <x: number>) - + derivált(<függvény: VégrehajthatóObjektum>, <x: szám>) derivative(<f: string>, <variable: string>, <x: number>) - + derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) From 1da1221c5149e505a9ceb5b3d9b316c6d549e304 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 10 Jan 2024 22:57:18 +0100 Subject: [PATCH 166/436] Updating icons --- .gitignore | 1 + LogarithmPlotter/logarithmplotter.svg | 73 +++++++- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 40 ++--- logplotter.svg | 165 ++++++------------ 4 files changed, 134 insertions(+), 145 deletions(-) diff --git a/.gitignore b/.gitignore index 11ffff4..8802201 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ linux/flatpak/.flatpak-builder *.jsc *.qmlc *.log +**/*.dxvk-cache .DS_Store **/.DS_Store **/__pycache__/ diff --git a/LogarithmPlotter/logarithmplotter.svg b/LogarithmPlotter/logarithmplotter.svg index 69f819d..77a2817 100644 --- a/LogarithmPlotter/logarithmplotter.svg +++ b/LogarithmPlotter/logarithmplotter.svg @@ -1,9 +1,64 @@ - - LogarithmPlotter Icon v1.0 - - - - - - - + +LogarithmPlotter Icon v1.0image/svg+xmlLogarithmPlotter Icon v1.02021Ad5001(c) Ad5001 2021 - All rights reserved diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 84be4f6..1352488 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -9,11 +9,11 @@ LogarithmPlotter http://apps.ad5001.eu/icons/apps/svg/logarithmplotter.svg - 2D logarithmic-scaled plotter software to make Bode plots, sequences and distribution functions - 2D-Grafiksoftware mit logarithmischer Skalierung zur Erstellung von Bode-Diagramms, Folgen und Verteilungsfunktionen - Logiciel de traçage 2D pour les diagrammes de Bode, les suites et les fonctions de répartition - Síkbeli ábrázolásszoftver Bode-ábrák, sorozatok és eloszlási funkciók készítéséhez - 2D-plotterprogramvare laget for opprettelse av Bode-diagram, sekvenser, og distribusjonsfunksjoner + Create and edit Bode plots + Erstellen und Bearbeiten von Bode-Diagrammen + Créez et éditez des diagrammes de Bode + Bode-diagramok létrehozása és szerkesztése + Opprette og redigere Bode-diagrammer diff --git a/logplotter.svg b/logplotter.svg index 89b2b1b..77a2817 100644 --- a/logplotter.svg +++ b/logplotter.svg @@ -1,131 +1,64 @@ - LogarithmPlotter Icon v1.0 - - - - - - - - image/svg+xml - - LogarithmPlotter Icon v1.0 - - 2021 - - - Ad5001 - - - - - (c) Ad5001 2021 - All rights reserved - - - - - - - - - - - - - - - LogarithmPlotter Icon v1.0image/svg+xmlLogarithmPlotter Icon v1.02021Ad5001(c) Ad5001 2021 - All rights reserved - - - - - - - - + d="M 18,4 C 18,10.017307 13.40948,15.5 5,15.5" /> From 874046960f7cb794096d45398cfff0fe8545ec8c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 10 Jan 2024 23:32:47 +0100 Subject: [PATCH 167/436] Changing linux descriptions --- linux/debian/changelog | 2 +- linux/debian/control | 2 +- snapcraft.yaml | 7 +------ 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/linux/debian/changelog b/linux/debian/changelog index 7daad8d..f21ff54 100644 --- a/linux/debian/changelog +++ b/linux/debian/changelog @@ -1,4 +1,4 @@ -logarithmplotter (0.3.0) stable; urgency=medium +logarithmplotter (0.4.0) stable; urgency=medium * Fully ported to PySide6 (Qt6). diff --git a/linux/debian/control b/linux/debian/control index db89220..a947351 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -10,4 +10,4 @@ Section: science Priority: optional Homepage: https://apps.ad5001.eu/logarithmplotter/ Installed-Size: 174 -Description: Create graphs with logarithm scales. +Description: Create and edit Bode plots diff --git a/snapcraft.yaml b/snapcraft.yaml index 6610006..0fbd1c7 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,7 +1,7 @@ name: logarithmplotter title: LogarithmPlotter version: '0.5.0' -summary: 2D logarithmic-scaled plotter software to create asymptotic Bode plots +summary: Create and edit Bode plots confinement: strict base: core20 grade: stable @@ -14,10 +14,6 @@ architectures: run-on: amd64 plugs: - #gnome-3-38-2004: - # interface: content - # target: gnome-platform - # default-provider: gnome-3-38-2004:gnome-3-38-2004 gtk-3-themes: default-provider: gtk-common-themes:gtk-3-themes interface: content @@ -166,7 +162,6 @@ apps: - desktop-legacy - wayland - x11 - #- gnome-3-38-2004 - gsettings # Theme access for wayland - home # Storing configuration. - opengl # Rendering From f9a7443631a3a76314e4fb28e4c59aab703d33eb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 10 Jan 2024 23:42:17 +0100 Subject: [PATCH 168/436] New icons for macos and windows --- mac/logarithmplotter.iconset/icon_128x128.png | Bin 3036 -> 2887 bytes mac/logarithmplotter.iconset/icon_16x16.png | Bin 631 -> 856 bytes mac/logarithmplotter.iconset/icon_256x256.png | Bin 5810 -> 5161 bytes mac/logarithmplotter.iconset/icon_32x32.png | Bin 995 -> 1203 bytes mac/logarithmplotter.iconset/icon_512x512.png | Bin 12170 -> 10274 bytes win/logarithmplotter.ico | Bin 185354 -> 430066 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mac/logarithmplotter.iconset/icon_128x128.png b/mac/logarithmplotter.iconset/icon_128x128.png index 0f68d7b48019c148a7abc9faddcc22494715b877..369662e6b84a54df0d7c1f3ef008f86d07c0308b 100644 GIT binary patch delta 2881 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 czcK?#qeY!x_7T3(1O}$h82O0fd2LJ#7 delta 3031 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 M07*qoM6N<$f=~{7+W-In delta 607 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 E0rxJQ1^@s6 literal 12170 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 diff --git a/win/logarithmplotter.ico b/win/logarithmplotter.ico index f975ab59aaf63ed4ca0110099e8c860bbb783e04..cb8394914ed8bb5628c337951a1b041497285ce0 100644 GIT binary patch literal 430066 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 literal 185354 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%0DBcis0vWfmmoSn16hLul@t$|IY$j0qX$E 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 h Date: Thu, 11 Jan 2024 00:09:35 +0100 Subject: [PATCH 169/436] Fixing issue with derivative and integrals --- .../qml/eu/ad5001/LogarithmPlotter/js/math/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index 450ae6d..ed544ab 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -64,7 +64,7 @@ function parseArgumentsForFunction(args, usage1, usage2) { } else if(args.length == 2) { // Parse variable [f,variable] = args - if(typeof f != 'string' || typeof variable != 'number') + if(typeof f != 'string' || typeof variable != 'string') throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2)) f = parser.parse(f).toJSFunction(variable, currentVars) } else From fde2526c54dbfe60ab29b15d900d11383ec78beb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 00:11:09 +0100 Subject: [PATCH 170/436] Updating copyrights --- LogarithmPlotter/__init__.py | 2 +- LogarithmPlotter/__main__.py | 2 +- LogarithmPlotter/logarithmplotter.py | 2 +- .../qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/History/History.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml | 2 +- .../ObjectLists/Editor/CustomPropertyList.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml | 2 +- .../LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/About.qml | 4 ++-- .../qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml | 2 +- .../LogarithmPlotter/Setting/AutocompletionCategory.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml | 2 +- .../eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml | 2 +- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml | 2 +- .../eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/color.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/create.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/delete.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/name.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/position.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/historylib.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/domain.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/expression.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/latex.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js | 2 +- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js | 2 +- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/function.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/point.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/text.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parameters.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js | 2 +- .../qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js | 2 +- LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js | 2 +- LogarithmPlotter/util/config.py | 2 +- LogarithmPlotter/util/helper.py | 2 +- LogarithmPlotter/util/latex.py | 2 +- LogarithmPlotter/util/native.py | 2 +- LogarithmPlotter/util/update.py | 2 +- README.md | 2 +- run.py | 2 +- setup.py | 2 +- win/installer.nsi | 2 +- 75 files changed, 76 insertions(+), 76 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index cbf8ecc..cfbae9b 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/__main__.py b/LogarithmPlotter/__main__.py index 62b2568..6c86e82 100644 --- a/LogarithmPlotter/__main__.py +++ b/LogarithmPlotter/__main__.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index ea29f5f..f6f2cb3 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index adf2a34..7a33bce 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index 831bb15..df9503d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index b6562e3..69ddfdb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index 67a7431..041ddfa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 55ef234..64bef06 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 4e5a68e..5b77730 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 63acf76..3f2f5ab 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 44e4b73..78efdae 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index cf129af..1fd7364 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index 03b04c6..e7d7a6f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index 81374d4..ab3f2f7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index 565069a..afc8d61 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml index 406c348..d74c101 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/About.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -102,7 +102,7 @@ BaseDialog { wrapMode: Text.WordWrap textFormat: Text.RichText font.pixelSize: 13 - text: "Copyright © 2023 Ad5001 <mail@ad5001.eu>
    + text: "Copyright © 2021-2024 Ad5001 <mail@ad5001.eu>

    This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

    diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml index dda9e01..0220956 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Alert.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml index be69067..10fe87e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/BaseDialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index 54ef3af..f86af07 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml index 6061ac8..4b7ff8a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/FileDialog.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 2311821..dddafab 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml index fbd1a64..7002539 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/InsertCharacter.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml index bb152e3..4c6d29c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/ThanksTo.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml index cf42238..304b704 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/AutocompletionCategory.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml index 936718f..d701661 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index bde4962..fa3dece 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index 7fa45e7..f845eb9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml index 30724b2..221b3a3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ListSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index 00c1347..d1c4c9d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index ceca22f..208e3e9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index 5ac3cb9..0d80da4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js index ff4bc54..9f921b5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js index 96020fa..2baf532 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js index f47f686..8eca385 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js index 8f651d0..c70d2d0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js index 799d26b..9b712f2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js index aa0299e..89f97c3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js index 761d7c4..c171124 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js index 20f4c31..78981eb 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js index fb43342..d9fa812 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js index ed544ab..0858522 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js index b27dbc6..6c47a23 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js index 01b25b9..4a57746 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js index 1e84912..50883b2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index b3e6f51..352a386 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js index 3d13340..9ecb377 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js index d57f18d..90dd468 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js index 045cf48..8ee04cf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js index 896b0cf..bc31bac 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js index a1dca1f..aa43a08 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js index 52452f7..9604656 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js index 4ffd5a7..edf9d68 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js index 1f27690..effdee1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js index c8a30a5..e872876 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js index b5cc866..c08aac8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js index f132f47..f8b3fee 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js index b9abafd..eb1c3e0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js index 2e16fa9..b513ea2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js index 5321296..cea2864 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js index 03e4c9e..2ef194a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js index dab0969..53a5941 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js index a7d5d48..b2cc6bc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js index d723444..df880c5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js index 36d4111..5d1cb9f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js index e782e6f..9a907fa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js index 624b3a5..0b62f8f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js @@ -1,6 +1,6 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index 79c0bb7..f19e000 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index 8b28ecc..127e587 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index 3690f83..ce22bb7 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/native.py b/LogarithmPlotter/util/native.py index 40ec810..01d9022 100644 --- a/LogarithmPlotter/util/native.py +++ b/LogarithmPlotter/util/native.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index d159a7a..25400ce 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/README.md b/README.md index ba1f3b1..026528f 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ There are several ways to contribute to LogarithmPlotter. ## Legal notice LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition functions. - Copyright (C) 2023 Ad5001 + Copyright (C) 2021-2024 Ad5001 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/run.py b/run.py index a1d78a1..1481dba 100644 --- a/run.py +++ b/run.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/setup.py b/setup.py index 841664c..4058ac3 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ """ * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2023 Ad5001 + * Copyright (C) 2021-2024 Ad5001 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/win/installer.nsi b/win/installer.nsi index 7366cdd..449fa85 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -13,7 +13,7 @@ Unicode True !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" !define VERSION_SHORT "0.5.0" !define APP_VERSION "${VERSION_SHORT}.0" -!define COPYRIGHT "Ad5001 (c) 2023" +!define COPYRIGHT "Ad5001 (c) 2021-2024" !define DESCRIPTION "Create graphs with logarithm scales." !define REG_UNINSTALL "Software\Microsoft\Windows\CurrentVersion\Uninstall\LogarithmPlotter" From cff994d9d7f8ab7745c9f0a6862620231e22e2e4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 00:59:01 +0100 Subject: [PATCH 171/436] Fixing macos building --- mac/logarithmplotter.icns | Bin 29480 -> 28354 bytes scripts/build-macosx.sh | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mac/logarithmplotter.icns b/mac/logarithmplotter.icns index 46c62fa3ec9fb9ac877e7d023a1cd4ecc074374a..bd032dfab9ae320d9de6e562105f42be1b9f3cb4 100644 GIT binary patch literal 28354 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 literal 29480 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 diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index c528f1a..03da330 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -5,7 +5,7 @@ cd "$DIR/.." rm $(find . -name "*.qmlc") rm $(find . -name "*.pyc") -python3 -m pip install -U pyinstaller +python3 -m pip install -U pyinstaller<6.0 # Building translations cd "LogarithmPlotter/i18n/" From d0851b819f836d124f2f36c52f758afa042eb201 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 01:15:43 +0100 Subject: [PATCH 172/436] Updating windows installer --- scripts/build-wine.sh | 4 ++++ win/installer.nsi | 12 +++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index 53dd11c..be8ca58 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -28,3 +28,7 @@ rm dist/logarithmplotter/_internal/PySide6/Qt6WebEngineCore.dll # Remove the QtQuick styles that are unused rm -rf dist/logarithmplotter/_internal/PySide6/qml/QtQuick/Controls/{Imagine,Material,designer} + +# Remove unused tools +rm dist/logarithmplotter/_internal/PySide6/qml/{Qt3D,QtQuick3D} +rm dist/logarithmplotter/_internal/PySide6/Qt6{Pdf.dll,*3D*,Location.dll} diff --git a/win/installer.nsi b/win/installer.nsi index 449fa85..7c5b248 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -50,7 +50,7 @@ VIAddVersionKey "FileVersion" "${APP_VERSION}" !define MUI_PAGE_HEADER_SUBTEXT "${COPYRIGHT}" !define MUI_WELCOMEPAGE_TITLE "Install ${APP_NAME} v${VERSION_SHORT}" -!define MUI_WELCOMEPAGE_TEXT "Welcome to the ${APP_NAME} installer! Follow the steps provided by this installer to install ${APP_NAME}" +!define MUI_WELCOMEPAGE_TEXT "Thank you for downloading ${APP_NAME}! Follow the steps provided by this installer to install ${APP_NAME}." !define MUI_HEADERIMAGE_RIGHT ;Extra space for the title area ;!insertmacro MUI_WELCOMEPAGE_TITLE_3LINES @@ -89,7 +89,7 @@ Icon "logarithmplotter.ico" ;!define MUI_DIRECTORYPAGE_VARIABLE $INSTDIR !define MUI_INSTFILESPAGE_FINISHHEADER_TEXT "Success!" -!define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "${APP_NAME} v${VERSION_SHORT} was installed on your computer" +!define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "${APP_NAME} v${VERSION_SHORT} was installed on your computer." !define MUI_INSTFILESPAGE_ABORTHEADER_TEXT "There was an error during the installation process." !define MUI_INSTFILESPAGE_ABORTHEADER_SUBTEXT "${APP_NAME} v${VERSION_SHORT} was not installed on your computer." @@ -155,16 +155,10 @@ Icon "logarithmplotter.ico" Section "" SetOutPath $INSTDIR File logarithmplotter.exe - File *.dll - File *.pyd File *.md - ;File *.manifest - File *.zip File *.bmp File *.ico - File /r qml - File /r PySide6 - File /r shiboken6 + File /r _internal CreateShortcut "$SMPROGRAMS\LogarithmPlotter.lnk" "$INSTDIR\logarithmplotter.exe" From 2d6389bfd57e93f208e14ac652941a3f11b1d2c0 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 01:49:29 +0100 Subject: [PATCH 173/436] Updating images for CI --- ci/drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/drone.yml b/ci/drone.yml index 6dd5beb..3bcf9f2 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -12,7 +12,7 @@ steps: - git submodule update --init --recursive - name: Linux test - image: ad5001/ubuntu-pyside6-xvfb:jammy-6.5.0 + image: ad5001/ubuntu-pyside6-xvfb:jammy-6.6.1 commands: - xvfb-run python3 run.py --test-build --no-check-for-updates - xvfb-run python3 run.py --test-build --no-check-for-updates ./ci/test1.lpf @@ -39,7 +39,7 @@ steps: - name: Windows building - image: ad5001/ubuntu-pyside6-xvfb-wine:win7-6.5.0-rev1 + image: ad5001/ubuntu-pyside6-xvfb-wine:win10-6.6.1 commands: - bash scripts/build-wine.sh - bash scripts/package-wine.sh From 70b1ac09f71dc5ea12b1cb4a0a848ef291659aa1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 01:13:20 +0000 Subject: [PATCH 174/436] Translated using Weblate (German) Currently translated at 100.0% (271 of 271 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/de/ --- LogarithmPlotter/i18n/lp_de.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 13c83d9..0bb06bf 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -1629,7 +1629,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Usage: %1 - + Verwendung: %1 @@ -1637,27 +1637,28 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Usage: %1 or %2 - + Verwendung: %1 oder +%2 integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: ExecutableObject>, <x: Zahl>) derivative(<f: string>, <variable: string>, <x: number>) - + derivative(<f: String>, <Variablen: String>, <x: Zahl>)
    From 1f72c76fb4625f10613a640efd89b93ac780cc5b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 19:24:06 +0100 Subject: [PATCH 175/436] Releasing v0.5.0 --- CHANGELOG.md | 30 +++++++++++++++++++ LogarithmPlotter/__init__.py | 2 +- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 30 +++++++++---------- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c96005..be8eec8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## v0.5.0 (11 Jan 2023) + +**New** + + * New, reworked application icon. + * Graph is now mouse interactive: + * You can now drag to move and scroll to zoom! + * Builtin functions now provide usage when used in the autocomplete of the expression editor. + +**Changes** + + * When creating an object that can be positioned, new default behavior is to pick first instead of opening object settings. + * Icons with text now use the SVG's text element, allowing them to integrate better with the system's default font. + * Special characters popup is now context aware (e.g. no sub/supscript symbols in expressions). + * New symbols in special characters popup. + * Integrals and derivatives can now be provided with an executable object (e.g. Functions) instead of strings as function. + * New description on Linux. + +**Fixed bugs** + + * Fixing ∞ 'variable' in domains and expressions. + * Several other bugs related to constants in expresions were fixed as well. + * Builtin functions now send an error message when not provided with the proper arguments. + +**Internal changes** + + * Updated to PySide6 v6.6.1. + * Reworked continuous functions' rendering to make it faster. + * Removed old bits from an unfinished new parser that weren't used. + ## v0.4.0 (27 May 2023) **Changes** diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index cfbae9b..4b060a5 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -18,7 +18,7 @@ from shutil import which __VERSION__ = "0.5.0" -is_release = False +is_release = True # Check if development version, if so get the date of the latest git patch diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 1352488..7cb44f8 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -85,21 +85,21 @@ https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/ https://hosted.weblate.org/engage/logarithmplotter/ - https://apps.ad5001.eu/img/en/gain.png?v=0.4-light - https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.4-light - https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.4-light - https://apps.ad5001.eu/img/de/gain.png?v=0.4-light - https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.4-light - https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.4-light - https://apps.ad5001.eu/img/fr/gain.png?v=0.4-light - https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.4-light - https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.4-light - https://apps.ad5001.eu/img/hu/gain.png?v=0.4-light - https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.4-light - https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.4-light - https://apps.ad5001.eu/img/no/gain.png?v=0.4-light - https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.4-light - https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.4-light + https://apps.ad5001.eu/img/en/gain.png?v=0.5 + https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/de/gain.png?v=0.5 + https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/fr/gain.png?v=0.5 + https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/hu/gain.png?v=0.5 + https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/no/gain.png?v=0.5 + https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.5 From 557592708f293f5331f79ded5508e1c3fc5a2ae9 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 19:56:25 +0100 Subject: [PATCH 176/436] Fixing building for debian --- scripts/build-wine.sh | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build-wine.sh b/scripts/build-wine.sh index be8ca58..638ba1d 100644 --- a/scripts/build-wine.sh +++ b/scripts/build-wine.sh @@ -30,5 +30,5 @@ rm dist/logarithmplotter/_internal/PySide6/Qt6WebEngineCore.dll rm -rf dist/logarithmplotter/_internal/PySide6/qml/QtQuick/Controls/{Imagine,Material,designer} # Remove unused tools -rm dist/logarithmplotter/_internal/PySide6/qml/{Qt3D,QtQuick3D} +rm -r dist/logarithmplotter/_internal/PySide6/qml/{Qt3D,QtQuick3D} rm dist/logarithmplotter/_internal/PySide6/Qt6{Pdf.dll,*3D*,Location.dll} diff --git a/setup.py b/setup.py index 4058ac3..8a7408c 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ if "PREFIX" not in os.environ and sys.platform == 'linux': from getopt import getopt optlist, args = getopt(sys.argv, '', ['prefix=', 'root=']) for arg,value in optlist: - if arg == "prefix": + if arg == "prefix" or arg == "root": os.environ["PREFIX"] = value if "PREFIX" not in os.environ and sys.platform == 'linux': if "XDG_DATA_HOME" in os.environ: From f9b0bb99ce3107c9e4307f5c3806683b2969465c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 20:15:25 +0100 Subject: [PATCH 177/436] Updating appstream --- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 7cb44f8..259edb1 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -115,6 +115,50 @@ + + +

    Changes for v0.5.0:

    +

    New

    +
      +
    • New, reworked application icon.
    • +
    • Graph is now mouse interactive:
    • +
    • You can now drag to move and scroll to zoom!
    • +
    • Builtin functions now provide usage when used in the autocomplete of the expression editor.
    • +
    +

    Changes

    +
      +
    • When creating an object that can be positioned, new default behavior is to pick first instead of opening object settings.
    • +
    • Icons with text now use the SVG's text element, allowing them to integrate better with the system's default font.
    • +
    • Special characters popup is now context aware (e.g. no sub/supscript symbols in expressions).
    • +
    • New symbols in special characters popup.
    • +
    • Integrals and derivatives can now be provided with an executable object (e.g. Functions) instead of strings as function.
    • +
    • New description on Linux.
    • +
    +

    Fixed bugs

    +
      +
    • Fixing ∞ 'variable' in domains and expressions.
    • +
    • Several other bugs related to constants in expresions were fixed as well.
    • +
    • Builtin functions now send an error message when not provided with the proper arguments.
    • +
    +

    Internal changes

    +
      +
    • Updated to PySide6 v6.6.1.
    • +
    • Reworked continuous functions' rendering to make it faster.
    • +
    • Removed old bits from an unfinished new parser that weren't used.
    • +
    +
    + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-v0.5.0-setup.exe + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/LogarithmPlotter-v0.5.0-setup.dmg + + + https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-0.5.0.tar.gz + + +

    Changes for v0.4.0:

    From 33c790b11326cb8ecb0e0c7e909ccc51b0a59ba3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 21:20:23 +0100 Subject: [PATCH 178/436] Updating debian information --- linux/debian/changelog | 24 ++++++++++++++++++++++++ linux/debian/control | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/linux/debian/changelog b/linux/debian/changelog index f21ff54..bc80cc9 100644 --- a/linux/debian/changelog +++ b/linux/debian/changelog @@ -1,3 +1,27 @@ +logarithmplotter (0.5.0) stable; urgency=medium + + * New, reworked application icon. + * Graph is now mouse interactive: + * You can now drag to move and scroll to zoom! + * Builtin functions now provide usage when used in the autocomplete of the expression editor. + + * Changed: When creating an object that can be positioned, new default behavior is to pick first instead of opening object settings. + * Changed: Icons with text now use the SVG's text element, allowing them to integrate better with the system's default font. + * Changed: Special characters popup is now context aware (e.g. no sub/supscript symbols in expressions). + * Changed: New symbols in special characters popup. + * Changed: Integrals and derivatives can now be provided with an executable object (e.g. Functions) instead of strings as function. + * Changed: New description on Linux. + + * Fixed: Fixing ∞ 'variable' in domains and expressions. + * Fixed: Several other bugs related to constants in expresions were fixed as well. + * Fixed: Builtin functions now send an error message when not provided with the proper arguments. + +**Internal changes** + + * Updated to PySide6 v6.6.1. + * Reworked continuous functions' rendering to make it faster. + * Removed old bits from an unfinished new parser that weren't used. + logarithmplotter (0.4.0) stable; urgency=medium * Fully ported to PySide6 (Qt6). diff --git a/linux/debian/control b/linux/debian/control index a947351..15e0846 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -1,6 +1,6 @@ Package: logarithmplotter Source: logarithmplotter -Version: 0.4.0 +Version: 0.5.0 Architecture: all Maintainer: Ad5001 Depends: python3, python3-pip, python3-pyside6-essentials (>= 6.4.0), texlive-latex-base, dvipng From 80f1077b35e1d4d9d87558f80a6a8eb3d905a021 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 11 Jan 2024 23:28:42 +0100 Subject: [PATCH 179/436] Updating snapcraft --- snapcraft.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index 0fbd1c7..c6632f9 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -3,15 +3,14 @@ title: LogarithmPlotter version: '0.5.0' summary: Create and edit Bode plots confinement: strict -base: core20 +base: core22 grade: stable icon: LogarithmPlotter/logarithmplotter.svg adopt-info: linuxfiles license: GPL-3.0+ architectures: - - build-on: amd64 - run-on: amd64 + - amd64 plugs: gtk-3-themes: From f73012104710f748e4557c4d94bede0e743da7c7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 6 Mar 2024 18:52:58 +0100 Subject: [PATCH 180/436] Fixing the icon on wayland, building on MacOS, and date on changelog --- CHANGELOG.md | 2 +- LogarithmPlotter/logarithmplotter.py | 1 + scripts/build-macosx.sh | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be8eec8..c4b7c6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## v0.5.0 (11 Jan 2023) +## v0.5.0 (11 Jan 2024) **New** diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index f6f2cb3..1071c81 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -89,6 +89,7 @@ def run(): QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(argv) app.setApplicationName("LogarithmPlotter") + app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) diff --git a/scripts/build-macosx.sh b/scripts/build-macosx.sh index 03da330..1946ad3 100755 --- a/scripts/build-macosx.sh +++ b/scripts/build-macosx.sh @@ -5,7 +5,7 @@ cd "$DIR/.." rm $(find . -name "*.qmlc") rm $(find . -name "*.pyc") -python3 -m pip install -U pyinstaller<6.0 +python3 -m pip install -U "pyinstaller<6.0" # Building translations cd "LogarithmPlotter/i18n/" From a6fcf6da19da0a308f191796dbc6a25ee3c3b5a7 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 25 Mar 2024 18:58:07 +0100 Subject: [PATCH 181/436] Fixing sequence no longer working with current rendering method. --- .../qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js index 352a386..cd0960a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js @@ -65,11 +65,15 @@ class Sequence extends Expr.Expression { cache(n = 1) { var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) var expr = C.parser.parse(str).simplify() + // Chache values required for this one. + if(!this.calcValues[n-this.valuePlus] && n-this.valuePlus > 0) + this.cache(n-this.valuePlus) + // Setting current variables C.currentVars = Object.assign( {'n': n-this.valuePlus}, // Just in case, add n (for custom functions) - C.currentObjectsByName + C.currentObjectsByName, + {[this.name]: this.calcValues} ) - C.currentVars[this.name] = this.calcValues this.calcValues[n] = expr.evaluate(C.currentVars) } From 08fea34366b30cc36115dee59cbbc63618c6538d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 28 Mar 2024 03:09:37 +0100 Subject: [PATCH 182/436] Converting as many JS libraries to ECMAScript modules. --- LogarithmPlotter/i18n/lp_de.ts | 473 ++++------- LogarithmPlotter/i18n/lp_en.ts | 473 ++++------- LogarithmPlotter/i18n/lp_es.ts | 803 ++++-------------- LogarithmPlotter/i18n/lp_fr.ts | 473 ++++------- LogarithmPlotter/i18n/lp_hu.ts | 469 ++++------ LogarithmPlotter/i18n/lp_nb_NO.ts | 711 ++++------------ LogarithmPlotter/i18n/lp_template.ts | 803 ++++-------------- LogarithmPlotter/i18n/update.sh | 2 +- LogarithmPlotter/logarithmplotter.py | 1 + .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 14 +- .../LogarithmPlotter/History/History.qml | 10 +- .../History/HistoryBrowser.qml | 2 +- .../LogarithmPlotter/History/HistoryItem.qml | 2 +- .../LogarithmPlotter/LogGraphCanvas.qml | 9 +- .../LogarithmPlotter/LogarithmPlotter.qml | 37 +- .../ObjectLists/Editor/CustomPropertyList.qml | 25 +- .../ObjectLists/Editor/Dialog.qml | 20 +- .../ObjectLists/ObjectCreationGrid.qml | 13 +- .../ObjectLists/ObjectLists.qml | 21 +- .../ObjectLists/ObjectRow.qml | 26 +- .../LogarithmPlotter/PickLocationOverlay.qml | 9 +- .../LogarithmPlotter/Popup/GreetScreen.qml | 1 - .../Setting/ExpressionEditor.qml | 23 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 4 +- .../ViewPositionChangeOverlay.qml | 5 +- .../js/history/{color.js => color.mjs} | 9 +- .../js/history/{common.js => common.mjs} | 46 +- .../js/history/{create.js => create.mjs} | 12 +- .../js/history/{delete.js => delete.mjs} | 12 +- .../{editproperty.js => editproperty.mjs} | 33 +- .../js/history/{name.js => name.mjs} | 15 +- .../js/history/{position.js => position.mjs} | 20 +- .../history/{visibility.js => visibility.mjs} | 8 +- .../js/{historylib.js => historylib.mjs} | 37 +- .../js/{ => lib/expr-eval}/expr-eval.js | 0 .../js/lib/expr-eval/integration.js | 121 +++ .../autoload.js => lib/qmlpolyfills.mjs} | 40 +- .../ad5001/LogarithmPlotter/js/math/common.js | 99 --- .../js/math/{domain.js => domain.mjs} | 171 ++-- .../js/math/{expression.js => expression.mjs} | 44 +- .../ad5001/LogarithmPlotter/js/math/latex.js | 282 ------ .../ad5001/LogarithmPlotter/js/math/latex.mjs | 288 +++++++ .../js/math/{sequence.js => sequence.mjs} | 46 +- .../js/{mathlib.js => mathlib.mjs} | 33 +- .../eu/ad5001/LogarithmPlotter/js/modules.js | 7 + .../eu/ad5001/LogarithmPlotter/js/objects.js | 96 --- .../eu/ad5001/LogarithmPlotter/js/objects.mjs | 112 +++ .../LogarithmPlotter/js/objs/autoload.mjs | 42 + .../js/objs/{common.js => common.mjs} | 154 ++-- .../js/objs/{function.js => function.mjs} | 48 +- .../js/objs/{gainbode.js => gainbode.mjs} | 62 +- .../js/objs/{phasebode.js => phasebode.mjs} | 44 +- .../js/objs/{point.js => point.mjs} | 16 +- .../objs/{repartition.js => repartition.mjs} | 23 +- .../js/objs/{sequence.js => sequence.mjs} | 36 +- .../{sommegainsbode.js => sommegainsbode.mjs} | 59 +- ...sommephasesbode.js => sommephasesbode.mjs} | 54 +- .../js/objs/{text.js => text.mjs} | 16 +- .../js/objs/{xcursor.js => xcursor.mjs} | 18 +- .../js/{parameters.js => parameters.mjs} | 10 +- .../LogarithmPlotter/js/parsing/README.md | 2 +- .../js/parsing/{common.js => common.mjs} | 5 +- .../js/parsing/{parsing.js => parsing.mjs} | 26 +- .../js/parsing/{polyfill.js => polyfill.mjs} | 25 +- .../parsing/{reference.js => reference.mjs} | 27 +- .../parsing/{tokenizer.js => tokenizer.mjs} | 39 +- .../eu/ad5001/LogarithmPlotter/js/runtime.mjs | 45 + .../js/{utils.js => utils.mjs} | 148 ++-- 68 files changed, 2604 insertions(+), 4255 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{color.js => color.mjs} (93%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{common.js => common.mjs} (72%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{create.js => create.mjs} (81%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{delete.js => delete.mjs} (83%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{editproperty.js => editproperty.mjs} (86%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{name.js => name.mjs} (83%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{position.js => position.mjs} (89%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/{visibility.js => visibility.mjs} (92%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{historylib.js => historylib.mjs} (66%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{ => lib/expr-eval}/expr-eval.js (100%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{objs/autoload.js => lib/qmlpolyfills.mjs} (53%) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/{domain.js => domain.mjs} (79%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/{expression.js => expression.mjs} (63%) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/{sequence.js => sequence.mjs} (66%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{mathlib.js => mathlib.mjs} (54%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{common.js => common.mjs} (77%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{function.js => function.mjs} (90%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{gainbode.js => gainbode.mjs} (67%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{phasebode.js => phasebode.mjs} (76%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{point.js => point.mjs} (91%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{repartition.js => repartition.mjs} (92%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{sequence.js => sequence.mjs} (78%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{sommegainsbode.js => sommegainsbode.mjs} (72%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{sommephasesbode.js => sommephasesbode.mjs} (74%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{text.js => text.mjs} (92%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/{xcursor.js => xcursor.mjs} (95%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{parameters.js => parameters.mjs} (96%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{common.js => common.mjs} (93%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{parsing.js => parsing.mjs} (60%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{polyfill.js => polyfill.mjs} (88%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{reference.js => reference.mjs} (91%) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/{tokenizer.js => tokenizer.mjs} (84%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{utils.js => utils.mjs} (75%) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 0bb06bf..2aad151 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter Über LogarithmPlotter @@ -33,147 +33,147 @@ AppMenuBar - + &File &Datei - + &Load... &Laden… - + &Save &Speichern - + Save &As... Speichern &Unter… - + &Quit &Ausfahrt - + &Edit &Bearbeiten - + &Undo &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + &Create &Erstellen - + &Settings &Einstellungen - + Check for updates on startup Beim Starten auf Updates prüfen - + Reset redo stack automaticly Wiederherstellen-Stapel automatisch zurücksetzen - + Enable LaTeX rendering LaTeX-Rendering aktivieren - + Expression editor Ausdruckseditor - + Automatically close parenthesises and brackets Klammern automatisch schließen - + Enable syntax highlighting Syntaxhervorhebung einschalten - + Enable autocompletion Automatische Vervollständigung einschalten - + Color Scheme Syntaktische Färbung - + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 Eigenschaften von %1 %2 bearbeiten - + LogarithmPlotter - Invalid object name LogarithmPlotter - Ungültiger Objektname - + An object with the name '%1' already exists. Ein Objekt mit dem Namen '%1' existiert bereits. - + Name Name - + Label content Etikett - + null leer - + name Name - + name + value Name + Wert @@ -260,62 +260,62 @@ EditorDialog Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten Name - Name + Name Label content - Etikett + Etikett null - leer + leer name - Name + Name name + value - Name + Wert + Name + Wert + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktion - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -336,69 +336,69 @@ GreetScreen - + Welcome to LogarithmPlotter Willkommen bei LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Nehmen Sie sich ein paar Sekunden Zeit, um LogarithmPlotter zu konfigurieren. Diese Einstellungen können jederzeit über das Menü "Einstellungen" geändert werden. - + Check for updates on startup (requires online connectivity) Beim Start nach Updates suchen (Online-Verbindung erforderlich) - + Reset redo stack when a new action is added to history Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird - + Enable LaTeX rendering LaTeX-Rendering aktivieren - + Automatically close parenthesises and brackets in expressions Automatisches Schließen von Klammern in Ausdrücken - + Enable syntax highlighting for expressions Syntaxhervorhebung für Ausdrücke einschalten - + Enable autocompletion interface in expression editor Schnittstelle zur automatischen Vervollständigung im Ausdruckseditor aktivieren - + Color scheme: Syntaktische Färbung Thema: - + User manual Benutzerhandbuch - + Changelog Changelog - + Done Schließen @@ -437,62 +437,62 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter - + Objects Objekte - + Settings Einstellungen - + History Verlauf - + Saved plot to '%1'. Gespeicherte Grafik auf '%1'. - + Loading file '%1'. Laden der Datei '%1'. - + Unknown object type: %1. Unbekannter Objekttyp: %1. - + Invalid file provided. Ungültige Datei angegeben. - + Could not save file: Die Datei konnte nicht gespeichert werden: - + Loaded file '%1'. Geladene Datei '%1'. - + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! - + &Update &Aktualisieren - + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -500,7 +500,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" ObjectCreationGrid - + + Create new: + Neu erstellen: @@ -513,55 +513,55 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Alle %1 ausblenden - + Show all %1 Alle %1 anzeigen Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen Delete %1 %2 - %1 %2 löschen + %1 %2 löschen Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen ObjectRow - + Hide %1 %2 Ausblenden %1 %2 - + Show %1 %2 Anzeigen %1 %2 - + Set %1 %2 position Position von %1 %2 einstellen - + Delete %1 %2 %1 %2 löschen - + Pick new color for %1 %2 Neue Farbe für %1 %2 auswählen @@ -569,41 +569,41 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" PickLocationOverlay - + Pointer precision: Genauigkeit des Zeigers: Snap to grid - Am Gitter einrasten + Am Gitter einrasten - + Snap to grid: Am Raster einrasten: - + Pick X X nehmen - + Pick Y Y nehmen - + Open picker settings Zeigereinstellungen öffnen - + Hide picker settings Zeigereinstellungen ausblenden - + (no pick selected) (keine Auswahl ausgewählt) @@ -815,8 +815,6 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" color - - %1 %2's color changed from %3 to %4. %1 %2 wurde von %3 bis %4 umgefärbt. @@ -824,27 +822,22 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" comment - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) - Note: Specify the probability for each value. Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… - If you have latex enabled, you can use use latex markup in between $$ to create equations. Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -852,9 +845,9 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" control - + - + %1: @@ -864,8 +857,6 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create - - New %1 %2 created. Neu %1 %2 erstellt. @@ -873,8 +864,6 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" delete - - %1 %2 deleted. %1 %2 gelöscht. @@ -882,12 +871,10 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" editproperty - %1 of %2 %3 changed from "%4" to "%5". %1 von %2 %3 wurde von "%4" auf "%5" geändert. - %1 of %2 changed from %3 to %4. %1 von %2 wurde von %3 auf %4 geändert. @@ -895,176 +882,166 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" error - - + + Cannot find property %1 of object %2. Eigenschaft %1 von Objekt %2 kann nicht gefunden werden. - + Undefined variable %1. Die Variable %1 ist nicht definiert. - + In order to be executed, object %1 must have at least one argument. Um als Funktion verwendet zu werden, benötigt das Objekt %1 mindestens ein Parameter. - + %1 cannot be executed. %1 ist keine Formel. - - - + + + Invalid expression. Ungültiger Ausdruck. - + Invalid expression (parity). Ungültiger Ausdruck (Parität). - + Unknown character "%1". Unbekanntes Schriftzeichen "%1". - - + + Illegal escape sequence: %1. Unzulässige Escapesequenz: %1. - - + + Parse error [%1:%2]: %3 Analysefehler [%1:%2]: %3 - + Expected %1 Erwartet %1 - + Unexpected %1 Unerwartetes %1 Function definition is not permitted. - Funktionsdefinition ist nicht erlaubt. + Funktionsdefinition ist nicht erlaubt. Expected variable for assignment. - Erwartete Variable für Zuweisung. + Erwartete Variable für Zuweisung. - + Unexpected ".": member access is not permitted Unerwartetes ".": Mitgliederzugriff ist nicht erlaubt - + Unexpected "[]": arrays are disabled. Unerwartetes "[]": Arrays sind deaktiviert. - + Unexpected symbol: %1. Unerwartetes Symbol: %1. - - + + Function %1 must have at least one argument. Die Funktion %1 benötigt mindestens ein Parameter. - - + First argument to map is not a function. Der erste Parameter von map ist keine Formel. - - + Second argument to map is not an array. Der zweite Parameter von map ist kein Array. - - + First argument to fold is not a function. Der erste Parameter für fold ist keine Formel. - - + Second argument to fold is not an array. Der zweite Parameter für fold ist kein Array. - - - + First argument to filter is not a function. Der erste Parameter für filter ist keine Formel. - - - + Second argument to filter is not an array. Der zweite Parameter von filter ist kein Array. - - + Second argument to indexOf is not a string or array. Der zweite Parameter von indexOf ist kein String oder Array. - - + Second argument to join is not an array. Der zweite Parameter von join ist kein Array. - + EOF Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. - + Error while parsing expression for property %1: %2 @@ -1075,7 +1052,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + Error while attempting to draw %1 %2: %3 @@ -1089,13 +1066,13 @@ Die letzte Änderung wurde rückgängig gemacht. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler - + Error while parsing expression for property %1: %2 @@ -1106,7 +1083,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Fehler @@ -1114,12 +1091,10 @@ Ausdruck analysiert: %3 function - Function Funktion - Functions Funktionen @@ -1127,24 +1102,18 @@ Ausdruck analysiert: %3 gainbode - Bode Magnitude Bode-Magnitude - Bode Magnitudes Bode-Magnituden - - low-pass Tiefpass - - high-pass Hochpass @@ -1153,27 +1122,27 @@ Ausdruck analysiert: %3 historylib New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. Name of %1 %2 changed to %3. - Der Name von %1 %2 wurde in %3 geändert. + Der Name von %1 %2 wurde in %3 geändert. @@ -1193,7 +1162,7 @@ Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.o DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1206,7 +1175,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1217,11 +1186,29 @@ Der Prozess '{}' brauchte zu lange, um beendet zu werden: Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. + + main + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name - - %1 %2 renamed to %3. %1 %2 umbenannt in %3. @@ -1229,114 +1216,90 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde parameters - above ↑ Über - below ↓ Unter - - left ← Links - - right → Rechts - above-left ↖ Oben links - above-right ↗ Oben rechts - below-left ↙ Unten links - below-right ↘ Unten rechts - center >|< Zentrum - top ↑ Über - bottom ↓ Unter - top-left ↖ Oben links - top-right ↗ Oben rechts - bottom-left ↙ Unten links - bottom-right ↘ Unten rechts - application Anwendung - function Funktion - high Hoch - low Tief - Next to target Neben dem Ziel - With label Mit Etikett - Hidden Versteckt @@ -1344,12 +1307,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde phasebode - Bode Phase Bode-Phase - Bode Phases Bode-Phasen @@ -1357,12 +1318,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde point - Point Punkt - Points Punkte @@ -1370,12 +1329,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde position - Position of %1 %2 set from "%3" to "%4". %1 %2 wurde von "%3" nach "%4" verschoben. - Position of %1 set from %2 to %3. %1 wurde von %2 nach %3 verschoben. @@ -1383,175 +1340,125 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde prop - expression Ausdruck - definitionDomain Definitionsbereich - destinationDomain Reichweite - - - - - - - - - - labelPosition Position des Etiketts - displayMode Anzeigemodus - - - - - - - labelX X-Position des Etiketts - - drawPoints Unentschiedene Punkte - - drawDashedLines Gestrichelte Linien anzeigen - - om_0 ω₀ - pass Pass - gain Größenordnung - omGraduation Teilung auf ω zeigen - phase Phase - unit Einheit - - - x X - - y Y - pointStyle Punkt-Stil - probabilities Wahrscheinlichkeiten - text Inhalt - disableLatex LaTeX-Rendering für diesen Text deaktivieren - targetElement Zielobjekt - approximate Ungefähren Wert anzeigen - rounding Rundung - displayStyle Stil - targetValuePosition Wertposition des Ziels - defaultExpression Standardausdruck - baseValues Initialisierungswerte color - Farbe + Farbe repartition - Repartition Verteilungsfunktion - Repartition functions Verteilungsfunktionen @@ -1559,12 +1466,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sequence - Sequence Folge - Sequences Folgen @@ -1572,8 +1477,6 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sommegainsbode - - Bode Magnitudes Sum Bode-Magnituden Summe @@ -1581,8 +1484,6 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde sommephasesbode - - Bode Phases Sum Bode-Phasen Summe @@ -1590,12 +1491,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde text - Text Text - Texts Texte @@ -1608,7 +1507,7 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. @@ -1626,37 +1525,37 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde usage - - + + Usage: %1 Verwendung: %1 - - - + + + Usage: %1 or %2 Verwendung: %1 oder %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: Zahl>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: String>, <Variablen: String>, <x: Zahl>) @@ -1664,14 +1563,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde visibility - - %1 %2 shown. %1 %2 angezeigt. - - %1 %2 hidden. %1 %2 ausgeblendet. @@ -1679,12 +1574,10 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde xcursor - X Cursor X Zeiger - X Cursors X Zeiger diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 91b0e51..591e2c2 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter About LogarithmPlotter @@ -33,147 +33,147 @@ AppMenuBar - + &File &File - + &Load... &Open… - + &Save &Save - + Save &As... Save &As… - + &Quit &Quit - + &Edit &Edit - + &Undo &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + &Create &Create - + &Settings &Settings - + Check for updates on startup Check for updates on startup - + Reset redo stack automaticly Reset redo stack automatically - + Enable LaTeX rendering Enable LaTeX rendering - + Expression editor Expression editor - + Automatically close parenthesises and brackets Automatically close parentheses and brackets - + Enable syntax highlighting Enable syntax highlighting - + Enable autocompletion Enable autocompletion - + Color Scheme Color Scheme - + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. An object with the name '%1' already exists. - + Name Name - + Label content Label content - + null null - + name name - + name + value name + value @@ -260,62 +260,62 @@ EditorDialog Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 Name - Name + Name Label content - Label content + Label content null - null + null name - name + name name + value - name + value + name + value + Create new %1 - + Create new %1 + + Create new %1 ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -336,69 +336,69 @@ GreetScreen - + Welcome to LogarithmPlotter Welcome to LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history Reset redo stack when a new action is added to history - + Enable LaTeX rendering Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions Automatically close parentheses and brackets in expressions - + Enable syntax highlighting for expressions Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor Enable autocompletion interface in expression editor - + Color scheme: Color scheme: - + User manual User manual - + Changelog Changelog - + Done Done @@ -437,62 +437,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects Objects - + Settings Settings - + History History - + Saved plot to '%1'. Saved plot to '%1'. - + Loading file '%1'. Loading file '%1'. - + Unknown object type: %1. Unknown object type: %1. - + Invalid file provided. Invalid file provided. - + Could not save file: Could not save file: - + Loaded file '%1'. Loaded file '%1'. - + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! - + &Update &Update - + &Update LogarithmPlotter &Update LogarithmPlotter @@ -500,7 +500,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: + Create new: @@ -513,55 +513,55 @@ These settings can be changed at any time from the "Settings" menu.Hide all %1 - + Show all %1 Show all %1 Hide %1 %2 - Hide %1 %2 + Hide %1 %2 Show %1 %2 - Show %1 %2 + Show %1 %2 Set %1 %2 position - Set %1 %2 position + Set %1 %2 position Delete %1 %2 - Delete %1 %2 + Delete %1 %2 Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 ObjectRow - + Hide %1 %2 Hide %1 %2 - + Show %1 %2 Show %1 %2 - + Set %1 %2 position Set %1 %2 position - + Delete %1 %2 Delete %1 %2 - + Pick new color for %1 %2 Pick new color for %1 %2 @@ -569,41 +569,41 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: Pointer precision: Snap to grid - Snap to grid + Snap to grid - + Snap to grid: Snap to grid: - + Pick X Pick X - + Pick Y Pick Y - + Open picker settings Open picker settings - + Hide picker settings Hide picker settings - + (no pick selected) (no pick selected) @@ -815,8 +815,6 @@ These settings can be changed at any time from the "Settings" menu. color - - %1 %2's color changed from %3 to %4. %1 %2's color changed from %3 to %4. @@ -824,27 +822,22 @@ These settings can be changed at any time from the "Settings" menu. comment - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) - Note: Specify the probability for each value. Note: Specify the probability for each value. - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… - If you have latex enabled, you can use use latex markup in between $$ to create equations. If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -852,9 +845,9 @@ These settings can be changed at any time from the "Settings" menu. control - + - + %1: @@ -864,8 +857,6 @@ These settings can be changed at any time from the "Settings" menu. create - - New %1 %2 created. New %1 %2 created. @@ -873,8 +864,6 @@ These settings can be changed at any time from the "Settings" menu. delete - - %1 %2 deleted. %1 %2 deleted. @@ -882,12 +871,10 @@ These settings can be changed at any time from the "Settings" menu. editproperty - %1 of %2 %3 changed from "%4" to "%5". %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 changed from %3 to %4. %1 of %2 changed from %3 to %4. @@ -895,176 +882,166 @@ These settings can be changed at any time from the "Settings" menu. error - - + + Cannot find property %1 of object %2. Cannot find property %1 of object %2. - + Undefined variable %1. Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. %1 is not a function. - - - + + + Invalid expression. Invalid expression. - + Invalid expression (parity). Invalid expression (parity). - + Unknown character "%1". Unknown character "%1". - - + + Illegal escape sequence: %1. Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 Parse error [%1:%2]: %3 - + Expected %1 Expected %1 - + Unexpected %1 Unexpected %1 Function definition is not permitted. - Function definition is not permitted. + Function definition is not permitted. Expected variable for assignment. - Expected variable for assignment. + Expected variable for assignment. - + Unexpected ".": member access is not permitted Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. Unexpected symbol: %1. - - + + Function %1 must have at least one argument. Function %1 must have at least one argument. - - + First argument to map is not a function. First argument to map is not a function. - - + Second argument to map is not an array. Second argument to map is not an array. - - + First argument to fold is not a function. First argument to fold is not a function. - - + Second argument to fold is not an array. Second argument to fold is not an array. - - - + First argument to filter is not a function. First argument to filter is not a function. - - - + Second argument to filter is not an array. Second argument to filter is not an array. - - + Second argument to indexOf is not a string or array. Second argument to indexOf is not a string or array. - - + Second argument to join is not an array. Second argument to join is not an array. - + EOF End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1075,7 +1052,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1089,13 +1066,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1106,7 +1083,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Drawing error @@ -1114,12 +1091,10 @@ Evaluated expression: %3 function - Function Function - Functions Functions @@ -1127,24 +1102,18 @@ Evaluated expression: %3 gainbode - Bode Magnitude Bode Magnitude - Bode Magnitudes Bode Magnitudes - - low-pass low-pass - - high-pass high-pass @@ -1153,27 +1122,27 @@ Evaluated expression: %3 historylib New %1 %2 created. - New %1 %2 created. + New %1 %2 created. %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. Name of %1 %2 changed to %3. - Name of %1 %2 changed to %3. + Name of %1 %2 changed to %3. @@ -1193,7 +1162,7 @@ Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.or DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1206,7 +1175,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1217,11 +1186,29 @@ Process '{}' took too long to finish: Please make sure your LaTeX installation is correct and report a bug if so. + + main + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name - - %1 %2 renamed to %3. %1 %2 renamed to %3. @@ -1229,114 +1216,90 @@ Please make sure your LaTeX installation is correct and report a bug if so. parameters - above ↑ Above - below ↓ Below - - left ← Left - - right → Right - above-left ↖ Above left - above-right ↗ Above right - below-left ↙ Below left - below-right ↘ Below right - center >|< Center - top ↑ Top - bottom ↓ Bottom - top-left ↖ Top left - top-right ↗ Top right - bottom-left ↙ Bottom left - bottom-right ↘ Bottom right - application Application - function Function - high High - low Low - Next to target Next to target - With label With label - Hidden Hidden @@ -1344,12 +1307,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. phasebode - Bode Phase Bode Phase - Bode Phases Bode Phases @@ -1357,12 +1318,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. point - Point Point - Points Points @@ -1370,12 +1329,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. position - Position of %1 %2 set from "%3" to "%4". %1 %2 moved from "%3" to "%4". - Position of %1 set from %2 to %3. %1 moved from %2 to %3. @@ -1383,175 +1340,125 @@ Please make sure your LaTeX installation is correct and report a bug if so. prop - expression Expression - definitionDomain Domain - destinationDomain Range - - - - - - - - - - labelPosition Label position - displayMode Display mode - - - - - - - labelX Label's X position - - drawPoints Show points - - drawDashedLines Show dashed lines - - om_0 ω₀ - pass Pass - gain Magnitude gain - omGraduation Show graduation on ω₀ - phase Phase - unit Unit to use - - - x X - - y Y - pointStyle Point style - probabilities Probabilities list - text Content - disableLatex Disable LaTeX rendering for this text - targetElement Object to target - approximate Show approximate value - rounding Rounding - displayStyle Display style - targetValuePosition Target's value position - defaultExpression Default expression - baseValues Initialisation values color - Color + Color repartition - Repartition Distribution - Repartition functions Distribution functions @@ -1559,12 +1466,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. sequence - Sequence Sequence - Sequences Sequences @@ -1572,8 +1477,6 @@ Please make sure your LaTeX installation is correct and report a bug if so. sommegainsbode - - Bode Magnitudes Sum Bode Magnitudes Sum @@ -1581,8 +1484,6 @@ Please make sure your LaTeX installation is correct and report a bug if so. sommephasesbode - - Bode Phases Sum Bode Phases Sum @@ -1590,12 +1491,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. text - Text Text - Texts Texts @@ -1608,7 +1507,7 @@ Please make sure your LaTeX installation is correct and report a bug if so.An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. @@ -1626,37 +1525,37 @@ Please make sure your LaTeX installation is correct and report a bug if so. usage - - + + Usage: %1 Usage: %1 - - - + + + Usage: %1 or %2 Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) @@ -1664,14 +1563,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. visibility - - %1 %2 shown. %1 %2 shown. - - %1 %2 hidden. %1 %2 hidden. @@ -1679,12 +1574,10 @@ Please make sure your LaTeX installation is correct and report a bug if so. xcursor - X Cursor X Cursor - X Cursors X Cursors diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 11bbbc5..a9a0f09 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter Sobre LogarithmPlotter @@ -33,147 +33,147 @@ AppMenuBar - + &File &Archivo - + &Load... &Abrir… - + &Save &Guardar - + Save &As... Guardar &como… - + &Quit &Salida - + &Edit &Editar - + &Undo &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + &Create &Crear - + &Settings &Ajustes - + Check for updates on startup Comprobación de las actualizaciones al arrancar - + Reset redo stack automaticly Restablecer la pila de rehacer automáticamente - + Enable LaTeX rendering Activar el renderizado de LaTeX - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -259,32 +259,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -305,68 +305,68 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering Activar el renderizado de LaTeX - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done @@ -405,62 +405,62 @@ These settings can be changed at any time from the "Settings" menu.
    LogarithmPlotter - + Objects - + Settings - + History - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -468,7 +468,7 @@ These settings can be changed at any time from the "Settings" menu.
    ObjectCreationGrid - + + Create new: @@ -481,7 +481,7 @@ These settings can be changed at any time from the "Settings" menu. - + Show all %1 @@ -489,27 +489,27 @@ These settings can be changed at any time from the "Settings" menu. ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -517,37 +517,37 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -756,251 +756,173 @@ These settings can be changed at any time from the "Settings" menu.
    - - color - - - - %1 %2's color changed from %3 to %4. - - - - - comment - - - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - - - - - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - - - - - Note: Specify the probability for each value. - - - - - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - - - - - If you have latex enabled, you can use use latex markup in between $$ to create equations. - - - control - + - + %1: - - create - - - - New %1 %2 created. - - - - - delete - - - - %1 %2 deleted. - - - - - editproperty - - - %1 of %2 %3 changed from "%4" to "%5". - - - - - %1 of %2 changed from %3 to %4. - - - error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - - + First argument to map is not a function. - - + Second argument to map is not an array. - - + First argument to fold is not a function. - - + Second argument to fold is not an array. - - - + First argument to filter is not a function. - - - + Second argument to filter is not an array. - - + Second argument to indexOf is not a string or array. - - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1008,7 +930,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1019,13 +941,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1033,49 +955,11 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error - - function - - - Function - - - - - Functions - - - - - gainbode - - - Bode Magnitude - - - - - Bode Magnitudes - - - - - - low-pass - - - - - - high-pass - - - latex @@ -1091,7 +975,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1100,7 +984,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1109,381 +993,22 @@ Please make sure your latex installation is correct and report a bug if so. - name + main - - - %1 %2 renamed to %3. - - - - - parameters - - - above + + Could not open file "{}": +{} - - below + + Could not open file: "{}" +File does not exist. - - - left - - - - - - right - - - - - above-left - - - - - above-right - - - - - below-left - - - - - below-right - - - - - center - - - - - top - - - - - bottom - - - - - top-left - - - - - top-right - - - - - bottom-left - - - - - bottom-right - - - - - application - - - - - function - - - - - high - - - - - low - - - - - Next to target - - - - - With label - - - - - Hidden - - - - - phasebode - - - Bode Phase - - - - - Bode Phases - - - - - point - - - Point - - - - - Points - - - - - position - - - Position of %1 %2 set from "%3" to "%4". - - - - - Position of %1 set from %2 to %3. - - - - - prop - - - expression - - - - - definitionDomain - - - - - destinationDomain - - - - - - - - - - - - - - labelPosition - - - - - displayMode - - - - - - - - - - - labelX - - - - - - drawPoints - - - - - - drawDashedLines - - - - - - om_0 - - - - - pass - - - - - gain - - - - - omGraduation - - - - - phase - - - - - unit - - - - - - - x - - - - - - y - - - - - pointStyle - - - - - probabilities - - - - - text - - - - - disableLatex - - - - - targetElement - - - - - approximate - - - - - rounding - - - - - displayStyle - - - - - targetValuePosition - - - - - defaultExpression - - - - - baseValues - - - - - repartition - - - Repartition - - - - - Repartition functions - - - - - sequence - - - Sequence - - - - - Sequences - - - - - sommegainsbode - - - - Bode Magnitudes Sum - - - - - sommephasesbode - - - - Bode Phases Sum - - - - - text - - - Text - - - - - Texts + + Built with PySide6 (Qt) v{} and python v{} @@ -1495,7 +1020,7 @@ Please make sure your latex installation is correct and report a bug if so. - + No update available. @@ -1513,66 +1038,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - - visibility - - - - %1 %2 shown. - - - - - - %1 %2 hidden. - - - - - xcursor - - - X Cursor - - - - - X Cursors - - - diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index aeb408f..68b0f1a 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter À propos de LogarithmPlotter @@ -33,148 +33,148 @@ AppMenuBar - + &File &Fichier - + &Load... &Ouvrir… - + &Save &Sauvegarder - + Save &As... Sauvegarde &Sous… - + &Quit &Quitter - + &Edit &Édition - + &Undo &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + &Create &Créer - + &Settings &Paramètres - + Check for updates on startup Vérifier la présence de mise à jour au démarrage - + Reset redo stack automaticly Légèrement long, et pas forcément très compréhensible. Réinitialiser la pile d'action "Rétablir" automatiquement - + Enable LaTeX rendering Activer le rendu LaTeX - + Expression editor Éditeur de formule - + Automatically close parenthesises and brackets Fermer automatiquement les parenthèses et les crochets - + Enable syntax highlighting Activer la coloration syntaxique - + Enable autocompletion Activer l'autocomplétion - + Color Scheme Coloration Syntaxique - + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -203,13 +203,13 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -217,42 +217,42 @@ Dialog - + Edit properties of %1 %2 Changer les propriétés de %1 %2 - + LogarithmPlotter - Invalid object name LogarithmPlotter - Nom d'objet invalide - + An object with the name '%1' already exists. Un objet portant le nom '%1' existe déjà. - + Name Nom - + Label content Étiquette - + null vide - + name nom - + name + value nom + valeur @@ -261,63 +261,63 @@ EditorDialog Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 Name - Nom + Nom Label content - Étiquette + Étiquette null - vide + vide name - nom + nom name + value - nom + valeur + nom + valeur + Create new %1 Traduction non litéralle pour éviter les problèmes de genre. - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -338,59 +338,59 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenue sur LogarithmPlotter - + Version %1 Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Prenez quelques secondes pour configurer LogarithmPlotter. Ces paramètres peuvent être modifiés à tout moment à partir du menu "Paramètres". - + Enable LaTeX rendering Activer le rendu LaTeX - + Automatically close parenthesises and brackets in expressions Fermer automatiquement les parenthèses et les crochets dans les formules - + Enable syntax highlighting for expressions Activer la coloration syntaxique des formules - + Enable autocompletion interface in expression editor Activer l'interface d'autocomplétion dans l'éditeur de formules - + Color scheme: Thème de coloration syntaxique : - + User manual Manuel d'utilisation - + Changelog Historique des modifications - + Done Fermer @@ -401,12 +401,12 @@ These settings can always be changed at any time from the "Settings" m These settings can always be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) - + Reset redo stack when a new action is added to history Réinitialiser la pile d'action "Rétablir" lorsqu'une nouvelle action est ajoutée à l'historique @@ -445,62 +445,62 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter - + Objects Objets - + Settings Paramètres - + History Historique - + Saved plot to '%1'. Graphe sauvegardé dans '%1'. - + Loading file '%1'. Chargement du fichier '%1'. - + Unknown object type: %1. Type d'objet inconnu : %1. - + Invalid file provided. Fichier fourni invalide. - + Could not save file: Impossible de sauvegarder le fichier : - + Loaded file '%1'. Fichier '%1' chargé. - + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! - + &Update &Mise à jour - + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -508,7 +508,7 @@ These settings can always be changed at any time from the "Settings" m ObjectCreationGrid - + + Create new: + Créer : @@ -521,55 +521,55 @@ These settings can always be changed at any time from the "Settings" m Cacher tous les %1 - + Show all %1 Montrer tous les %1 Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 ObjectRow - + Hide %1 %2 Cacher l'objet %1 %2 - + Show %1 %2 Montrer l'objet %1 %2 - + Set %1 %2 position Définir la position de l'objet %1 %2 - + Delete %1 %2 Supprimer l'objet %1 %2 - + Pick new color for %1 %2 Choisissez une nouvelle couleur pour %1 %2 @@ -577,41 +577,41 @@ These settings can always be changed at any time from the "Settings" m PickLocationOverlay - + Pointer precision: Précision du pointeur : Snap to grid - Placement sur la grille + Placement sur la grille - + Snap to grid: Aligner sur la grille : - + Pick X Prendre la position X - + Pick Y Prendre la position Y - + Open picker settings Ouvrir les paramètres du pointeur - + Hide picker settings Cacher les paramètres du pointeur - + (no pick selected) (aucun axe sélectionné) @@ -823,8 +823,6 @@ These settings can always be changed at any time from the "Settings" m color - - %1 %2's color changed from %3 to %4. %1 %2 a été re colorisé du %3 au %4. @@ -832,28 +830,23 @@ These settings can always be changed at any time from the "Settings" m comment - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) - Note: Specify the probability for each value. Note : Spécifiez la probabilité pour chaque valeur. - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… - If you have latex enabled, you can use use latex markup in between $$ to create equations. Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -861,9 +854,9 @@ These settings can always be changed at any time from the "Settings" m control - + - + %1: @@ -873,8 +866,6 @@ These settings can always be changed at any time from the "Settings" m create - - New %1 %2 created. Nouvel objet %1 %2 créé. @@ -882,8 +873,6 @@ These settings can always be changed at any time from the "Settings" m delete - - %1 %2 deleted. %1 %2 supprimé(e). @@ -891,12 +880,10 @@ These settings can always be changed at any time from the "Settings" m editproperty - %1 of %2 %3 changed from "%4" to "%5". %1 de %2 %3 modifiée de "%4" à "%5". - %1 of %2 changed from %3 to %4. %1 de %2 modifiée de %3 à %4. @@ -904,176 +891,166 @@ These settings can always be changed at any time from the "Settings" m error - - + + Cannot find property %1 of object %2. Impossible de trouver la propriété %1 de l'objet %2. - + Undefined variable %1. La variable %1 n'est pas définie. - + In order to be executed, object %1 must have at least one argument. Pour être utilisé comme fonction, l'objet %1 nécessite au moins un argument. - + %1 cannot be executed. %1 n'est pas une fonction. - - - + + + Invalid expression. Formule invalide. - + Invalid expression (parity). Formule invalide (parité). - + Unknown character "%1". Le caractère "%1" est inconnu. - - + + Illegal escape sequence: %1. Séquence d'échappement illégale : %1. - - + + Parse error [%1:%2]: %3 Erreur de syntaxe [%1:%2] : %3 - + Expected %1 %1 attendu - + Unexpected %1 %1 inattendu Function definition is not permitted. - La définition de fonctions n'est pas autorisée. + La définition de fonctions n'est pas autorisée. Expected variable for assignment. - Une variable est attendue pour l'affectation. + Une variable est attendue pour l'affectation. - + Unexpected ".": member access is not permitted "." inattendu : l'accès aux propriétés n'est pas autorisé - + Unexpected "[]": arrays are disabled. "[]" inattendu : les tableaux sont désactivés. - + Unexpected symbol: %1. Symbole inconnu : %1. - - + + Function %1 must have at least one argument. La fonction %1 nécessite au moins un argument. - - + First argument to map is not a function. Le premier argument de map n'est pas une fonction. - - + Second argument to map is not an array. Le deuxième argument de map n'est pas un tableau. - - + First argument to fold is not a function. Le premier argument de fold n'est pas une fonction. - - + Second argument to fold is not an array. Le deuxième argument de fold n'est pas un tableau. - - - + First argument to filter is not a function. Le premier argument de filter n'est pas une fonction. - - - + Second argument to filter is not an array. Le deuxième argument de filter n'est pas un tableau. - - + Second argument to indexOf is not a string or array. Le deuxième argument de indexOf n'est ni chaîne de caractères ni un tableau. - - + Second argument to join is not an array. Le deuxième argument de join n'est pas un tableau. - + EOF Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. - + Error while parsing expression for property %1: %2 @@ -1084,7 +1061,7 @@ Evaluated expression: %3 Formule analysée : %3 - + Error while attempting to draw %1 %2: %3 @@ -1098,13 +1075,13 @@ La dernière modification a été annulée. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe - + Error while parsing expression for property %1: %2 @@ -1115,7 +1092,7 @@ Evaluated expression: %3 Formule analysée : %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Erreur @@ -1123,12 +1100,10 @@ Formule analysée : %3 function - Function Fonction - Functions Fonctions @@ -1136,24 +1111,18 @@ Formule analysée : %3 gainbode - Bode Magnitude Gain de Bode - Bode Magnitudes Gains de Bode - - low-pass passe-bas - - high-pass passe-haut @@ -1162,27 +1131,27 @@ Formule analysée : %3 historylib New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). Name of %1 %2 changed to %3. - Le nom de %1 %2 a été changé en %3. + Le nom de %1 %2 a été changé en %3. @@ -1202,7 +1171,7 @@ Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l&apos DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1215,7 +1184,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1226,11 +1195,29 @@ Le processus '{}' a mis trop de temps à se terminer : Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. + + main + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name - - %1 %2 renamed to %3. %1 %2 renommé(e) en %3. @@ -1238,114 +1225,90 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c parameters - above ↑ Au dessus - below ↓ En dessous - - left ← À gauche - - right → À droite - above-left ↖ Au dessus à gauche - above-right ↗ Au dessus à droite - below-left ↙ En dessous à gauche - below-right ↘ En dessous à droite - center >|< Centré - top ↑ Au dessus - bottom ↓ En dessous - top-left ↖ Au dessus à gauche - top-right ↗ Au dessus à droite - bottom-left ↙ En dessous à gauche - bottom-right ↘ En dessous à droite - application Application - function Fonction - high Haut - low Bas - Next to target A côté de la cible - With label Avec l'étiquette - Hidden Caché @@ -1353,12 +1316,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c phasebode - Bode Phase Phase de Bode - Bode Phases Phases de Bode @@ -1366,12 +1327,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c point - Point Point - Points Points @@ -1379,12 +1338,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c position - Position of %1 %2 set from "%3" to "%4". %1 %2 a été déplacé depuis "%3" vers "%4". - Position of %1 set from %2 to %3. %1 a été déplacé depuis %2 vers %3. @@ -1392,175 +1349,125 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c prop - expression Expression - definitionDomain Domaine de définition - destinationDomain Portée - - - - - - - - - - labelPosition Position de l'étiquette - displayMode Mode d'affichage - - - - - - - labelX Position en X de l'étiquette - - drawPoints Afficher les points - - drawDashedLines Afficher les pointillés - - om_0 ω₀ - pass Passe - gain Gain - omGraduation Afficher la graduation sur ω₀ - phase Phase - unit Unité de la phase - - - x X - - y Y - pointStyle Style du point - probabilities Liste de probabilités - text Contenu - disableLatex Désactiver le rendu LaTeX pour ce texte - targetElement Objet à cibler - approximate Afficher la valeur approximative - rounding Arrondi - displayStyle Style d'affichage - targetValuePosition Position de la valeur de la cible - defaultExpression Expression - baseValues Valeurs d'initialisation color - Couleur + Couleur repartition - Repartition Répartition - Repartition functions Fonctions de répartition @@ -1568,12 +1475,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sequence - Sequence Suite - Sequences Suites @@ -1581,8 +1486,6 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sommegainsbode - - Bode Magnitudes Sum Sommes des gains de Bode @@ -1590,8 +1493,6 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c sommephasesbode - - Bode Phases Sum Somme des phases de Bode @@ -1599,12 +1500,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c text - Text Texte - Texts Textes @@ -1617,7 +1516,7 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. @@ -1635,37 +1534,37 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c usage - - + + Usage: %1 Emploi : %1 - - - + + + Usage: %1 or %2 Emploi : %1 ou %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet exécutable>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f : Objet exécutable>, <x : nombre>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f : fonction chaîne>, <variable>, <x : nombre>) @@ -1673,14 +1572,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c visibility - - %1 %2 shown. %1 %2 affiché(e). - - %1 %2 hidden. %1 %2 cachée(e). @@ -1688,12 +1583,10 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c xcursor - X Cursor Curseur X - X Cursors Curseurs X diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 89396ce..5a311df 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter LogarithmPlotter névjegye @@ -33,147 +33,147 @@ AppMenuBar - + &File &Fájl - + &Load... &Betöltés… - + &Save &Mentés - + Save &As... Me&ntés másként… - + &Quit &Kilépés - + &Edit S&zerkesztés - + &Undo &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + &Create &Létrehozás - + &Settings &Beállítások - + Check for updates on startup Frissítések keresése indításkor - + Reset redo stack automaticly Ismétlési verem önműködő visszaállítása - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - + Expression editor Kifejezésszerkesztő - + Automatically close parenthesises and brackets Zárójelek automatikus bezárása - + Enable syntax highlighting Mondattani kiemelés engedélyezése - + Enable autocompletion Automatikus befejezés engedélyezése - + Color Scheme Színséma - + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 %1 %2 tulajdonságainak szerkesztése - + LogarithmPlotter - Invalid object name LogarithmPlotter - Érvénytelen objektumnév - + An object with the name '%1' already exists. A(z) „%1” nevű objektum már létezik. - + Name Név - + Label content Címketartalom - + null üres - + name név - + name + value név + érték @@ -260,62 +260,62 @@ EditorDialog Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése Name - Név + Név Label content - Címke tartalom + Címke tartalom null - üres + üres name - név + név name + value - név + érték + név + érték + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása ExpressionEditor - + Object Properties Objektumtulajdonságok - + Variables Változók - + Constants Állandók - + Functions Függvények - + Executable Objects Függvényobjektumok - + Objects Objektumok @@ -336,69 +336,69 @@ GreetScreen - + Welcome to LogarithmPlotter Isten hozott a LogarithmPlotter! - + Version %1 %1 verzió - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Szánjon néhány másodpercet a LogarithmPlotter beállításához. Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - + Check for updates on startup (requires online connectivity) Frissítések keresése indításkor (online kapcsolat szükséges) - + Reset redo stack when a new action is added to history Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez - + Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - + Automatically close parenthesises and brackets in expressions Zárójelek automatikus bezárása a kifejezésekben - + Enable syntax highlighting for expressions Mondattani kiemelés engedélyezése a kifejezésekhez - + Enable autocompletion interface in expression editor Automatikus befejezési felület engedélyezése a kifejezésszerkesztőben - + Color scheme: Színséma: - + User manual Használati utasítás - + Changelog Változásnapló - + Done Kész @@ -437,62 +437,62 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter - + Objects Tárgyak - + Settings Beállítások - + History Előzmények - + Saved plot to '%1'. Ábra mentve ide: „%1”. - + Loading file '%1'. A(z) „%1” fájl betöltése folyamatban van. - + Unknown object type: %1. Ismeretlen objektumtípus: %1. - + Invalid file provided. A megadott fájl érvénytelen. - + Could not save file: A fájl mentése nem sikerült: - + Loaded file '%1'. A(z) „%1” fájl betöltve. - + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! - + &Update &Frissítés - + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -500,7 +500,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. ObjectCreationGrid - + + Create new: + Új létrehozása: @@ -513,55 +513,55 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Összes %1 elrejtése - + Show all %1 Összes %1 megjelenítése Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása Delete %1 %2 - %1 %2 törlése + %1 %2 törlése Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 ObjectRow - + Hide %1 %2 %1 %2 elrejtése - + Show %1 %2 %1 %2 megjelenítése - + Set %1 %2 position %1 %2 helye beállítása - + Delete %1 %2 %1 %2 törlése - + Pick new color for %1 %2 Válasszon új színt a következőhöz: %1 %2 @@ -569,41 +569,41 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. PickLocationOverlay - + Pointer precision: Mutató pontossága: Snap to grid - Rácshoz illesztés + Rácshoz illesztés - + Snap to grid: Rácshoz igazítás: - + Pick X X kijelölése - + Pick Y Y kijelölése - + Open picker settings Kijelölési beállítások megnyitása - + Hide picker settings Kijelölési beállítások elrejtése - + (no pick selected) (nincs kijelölés kiválasztva) @@ -815,8 +815,6 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. color - - %1 %2's color changed from %3 to %4. %1 %2 színe %3-ról %4-re változott. @@ -824,27 +822,22 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. comment - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) - Note: Specify the probability for each value. Megjegyzés: Adja meg az egyes értékek valószínűségét. - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … - If you have latex enabled, you can use use latex markup in between $$ to create equations. Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -852,9 +845,9 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. control - + - + %1: @@ -864,8 +857,6 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create - - New %1 %2 created. Új %1 %2 létrehozva. @@ -873,8 +864,6 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. delete - - %1 %2 deleted. %1 %2 törölve. @@ -882,12 +871,10 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. editproperty - %1 of %2 %3 changed from "%4" to "%5". %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. - %1 of %2 changed from %3 to %4. %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -895,176 +882,166 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. error - - + + Cannot find property %1 of object %2. A(z) %2 objektum %1 tulajdonsága nem található. - + Undefined variable %1. A(z) %1 változó nincs meghatározva. - + In order to be executed, object %1 must have at least one argument. A végrehajtáshoz a(z) %1 objektumnak legalább egy argumentummal kell rendelkeznie. - + %1 cannot be executed. A(z) %1 nem függvény. - - - + + + Invalid expression. Érvénytelen kifejezés. - + Invalid expression (parity). Érvénytelen kifejezés (paritás). - + Unknown character "%1". Ismeretlen karakter „%1”. - - + + Illegal escape sequence: %1. Érvénytelen kilépési sorozat: %1. - - + + Parse error [%1:%2]: %3 Elemzési hiba [%1:%2]: %3 - + Expected %1 Várható %1 - + Unexpected %1 Váratlan %1 Function definition is not permitted. - A függvény meghatározása nem engedélyezett. + A függvény meghatározása nem engedélyezett. Expected variable for assignment. - A hozzárendeléshez várt változó. + A hozzárendeléshez várt változó. - + Unexpected ".": member access is not permitted Váratlan „.”: a tagok hozzáférése nem engedélyezett - + Unexpected "[]": arrays are disabled. Váratlan „[]”: a tömbök le vannak tiltva. - + Unexpected symbol: %1. Váratlan szimbólum: %1. - - + + Function %1 must have at least one argument. A(z) %1 függvénynek legalább egy argumentumnak kell lennie. - - + First argument to map is not a function. Az első leképezési argumentum nem függvény. - - + Second argument to map is not an array. A második leképezési argumentum nem tömb. - - + First argument to fold is not a function. Az első behajtási argumentum nem függvény. - - + Second argument to fold is not an array. A második behajtási argumentum nem tömb. - - - + First argument to filter is not a function. Az első szűrési argumentum nem függvény. - - - + Second argument to filter is not an array. A második szűrési argumentum nem tömb. - - + Second argument to indexOf is not a string or array. Az indexOf második argumentuma nem karakterlánc vagy tömb. - - + Second argument to join is not an array. A második csatlakozási argumentum nem tömb. - + EOF Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. - + Error while parsing expression for property %1: %2 @@ -1075,7 +1052,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + Error while attempting to draw %1 %2: %3 @@ -1089,13 +1066,13 @@ Az utolsó módosítás visszavonása. expression - - + + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba - + Error while parsing expression for property %1: %2 @@ -1106,7 +1083,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Rajzolási hiba @@ -1114,12 +1091,10 @@ Kiértékelt kifejezés: %3 function - Function Függvény - Functions Függvények @@ -1127,24 +1102,18 @@ Kiértékelt kifejezés: %3 gainbode - Bode Magnitude Bode-nagyságrend - Bode Magnitudes Bode-nagyságrendek - - low-pass aluláteresztő - - high-pass felüláteresztő @@ -1153,23 +1122,23 @@ Kiértékelt kifejezés: %3 historylib New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. @@ -1189,7 +1158,7 @@ Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1202,7 +1171,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1213,11 +1182,29 @@ A(z) „{}” folyamat túl sokáig tartott a befejezéshez: Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. + + main + + + Could not open file "{}": +{} + + + + + Could not open file: "{}" +File does not exist. + + + + + Built with PySide6 (Qt) v{} and python v{} + + + name - - %1 %2 renamed to %3. %1 %2 átnevezve erre: %3. @@ -1225,114 +1212,90 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents parameters - above ↑ Felett - below ↓ Alatt - - left ← Balra - - right → Jobbra - above-left ↖ Felett, balra - above-right ↗ Felett, jobbra - below-left ↙ Alatt, balra - below-right ↘ Alatt, jobbra - center >|< Középre - top ↑ Felső - bottom ↓ Alsó - top-left ↖ Bal felső - top-right ↗ Jobb felső - bottom-left ↙ Bal alsó - bottom-right ↘ Jobb alsó - application Alkalmazás - function Függvény - high Magas - low Alul - Next to target Cél mellé - With label Címkével - Hidden Rejtett @@ -1340,12 +1303,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents phasebode - Bode Phase Bode-fázis - Bode Phases Bode-fázisok @@ -1353,12 +1314,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents point - Point Pont - Points Pontok @@ -1366,12 +1325,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents position - Position of %1 %2 set from "%3" to "%4". %1 %2 áthelyezve innen: „%3” ide: „%4”. - Position of %1 set from %2 to %3. %1 áthelyezve innen: %2 ide: %3. @@ -1379,158 +1336,110 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents prop - expression Kifejezés - definitionDomain Abszcissza tartomány - destinationDomain Ordináta tartomány - - - - - - - - - - labelPosition Címke helyzete - displayMode Megjelenítési mód - - - - - - - labelX Címke X helyzete - - drawPoints Pontok megjelenítése - - drawDashedLines Szaggatott vonalak megjelenítése - - om_0 ω₀ - pass Áteresztő - gain Nagyságrend nyeresége - omGraduation ω₀ érettségi megjelenítése - phase Fázis - unit Egység használata - - - x X - - y Y - pointStyle Pontstílus - probabilities Valószínűségek listája - text Tartalom - disableLatex LaTeX-megjelenítés letiltása ennél a szövegnél - targetElement Tárgycél - approximate Hozzávetőleges érték megjelenítése - rounding Kerekítés - displayStyle Megjelenítési stílus - targetValuePosition Cél értékpozíciója - defaultExpression Alapértelmezett kifejezés - baseValues Kezdeményezési értékek @@ -1538,12 +1447,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents repartition - Repartition Elosztás - Repartition functions Elosztási függvények @@ -1551,12 +1458,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sequence - Sequence Sorozat - Sequences Sorozatok @@ -1564,8 +1469,6 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sommegainsbode - - Bode Magnitudes Sum Bode-nagyságrendek összege @@ -1573,8 +1476,6 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents sommephasesbode - - Bode Phases Sum Bode-fázisok összege @@ -1582,12 +1483,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents text - Text Szöveg - Texts Szövegek @@ -1600,7 +1499,7 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. @@ -1618,37 +1517,37 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents usage - - + + Usage: %1 Használat: %1 - - - + + + Usage: %1 or %2 Használat: %1 vagy %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) - + derivative(<f: ExecutableObject>, <x: number>) derivált(<függvény: VégrehajthatóObjektum>, <x: szám>) - + derivative(<f: string>, <variable: string>, <x: number>) derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) @@ -1656,14 +1555,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents visibility - - %1 %2 shown. %1 %2 megjelenítve. - - %1 %2 hidden. %1 %2 rejtve. @@ -1671,12 +1566,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents xcursor - X Cursor X kurzor - X Cursors X kurzorok diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 18d0f09..98fa6fb 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter Om @@ -33,147 +33,147 @@ AppMenuBar - + &File &Fil - + &Load... &Last inn … - + &Save &Lagre - + Save &As... Lagre &som … - + &Quit &Avslutt - + &Edit &Rediger - + &Undo &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + &Create &Opprett - + &Settings &Innstillinger - + Check for updates on startup Se etter nye versjoner ved programstart - + Reset redo stack automaticly Tilbakestill angrehistorikk automatisk - + Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + &Help &Hjelp - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 Rediger egenskaper for %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name Navn - + Label content Etikett-innhold - + null NULL - + name navn - + name + value navn + veri @@ -260,62 +260,62 @@ EditorDialog Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -336,69 +336,69 @@ GreetScreen - + Welcome to LogarithmPlotter Velkommen til LogarithmPlotter - + Version %1 Versjon %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Sett opp LogarithmPlotter. Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Check for updates on startup (requires online connectivity) Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) - + Reset redo stack when a new action is added to history Tilbakesitll angrehistorikk når en ny handling legges til - + Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done @@ -437,62 +437,62 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. LogarithmPlotter - + Objects Objekter - + Settings Innstillinger - + History Historikk - + Saved plot to '%1'. Lagret plott i «%1». - + Loading file '%1'. Laster inn «%1»-fil. - + Unknown object type: %1. Ukjent objekttype: %1. - + Invalid file provided. Ugyldig fil angitt. - + Could not save file: Kunne ikke lagre fil: - + Loaded file '%1'. Lastet inn filen «%1». - + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! - + &Update &Oppdater - + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -500,7 +500,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. ObjectCreationGrid - + + Create new: + Opprett ny: @@ -513,17 +513,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Skjul alle %1 - + Show all %1 Vis alle %1 Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position @@ -531,37 +531,37 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 ObjectRow - + Hide %1 %2 Skjul %1 %2 - + Show %1 %2 Vis %1 %2 - + Set %1 %2 position Sett %1 %2 posisjon - + Delete %1 %2 Slett %1 %2 - + Pick new color for %1 %2 Velg ny farge for %1 %2 @@ -569,41 +569,41 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. PickLocationOverlay - + Pointer precision: Peker-presisjon: Snap to grid - Fest til rutenett + Fest til rutenett - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -812,49 +812,12 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - - color - - - - %1 %2's color changed from %3 to %4. - - - - - comment - - - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - - - - - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - - - - - Note: Specify the probability for each value. - - - - - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - - - - - If you have latex enabled, you can use use latex markup in between $$ to create equations. - - - control - + - + %1: @@ -864,199 +827,179 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. create - - New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. delete - - %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. editproperty - %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». - - - - %1 of %2 changed from %3 to %4. - + %1 av %2 %3 endret fra «%4» til «%5». error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - - + First argument to map is not a function. - - + Second argument to map is not an array. - - + First argument to fold is not a function. - - + Second argument to fold is not an array. - - - + First argument to filter is not a function. - - - + Second argument to filter is not an array. - - + Second argument to indexOf is not a string or array. - - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1064,7 +1007,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1075,13 +1018,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1089,7 +1032,7 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error @@ -1097,12 +1040,10 @@ Evaluated expression: %3 function - Function Funksjon - Functions Funksjoner @@ -1110,24 +1051,18 @@ Evaluated expression: %3 gainbode - Bode Magnitude Bode-magnitude - Bode Magnitudes Bode-magnituder - - low-pass lavpass - - high-pass høypass @@ -1136,23 +1071,23 @@ Evaluated expression: %3 historylib New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». %1 %2 shown. - %1 %2 vist. + %1 %2 vist. %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. @@ -1170,7 +1105,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1179,7 +1114,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1188,138 +1123,32 @@ Please make sure your latex installation is correct and report a bug if so. - name + main - - - %1 %2 renamed to %3. - - - - - parameters - - - above + + Could not open file "{}": +{} - - below + + Could not open file: "{}" +File does not exist. - - - left - - - - - - right - - - - - above-left - - - - - above-right - - - - - below-left - - - - - below-right - - - - - center - - - - - top - - - - - bottom - - - - - top-left - - - - - top-right - - - - - bottom-left - - - - - bottom-right - - - - - application - - - - - function - - - - - high - - - - - low - - - - - Next to target - - - - - With label - - - - - Hidden + + Built with PySide6 (Qt) v{} and python v{} phasebode - Bode Phase Bode-fase - Bode Phases Bode-faser @@ -1327,197 +1156,21 @@ Please make sure your latex installation is correct and report a bug if so. point - Point Punkt - Points Punkter - - position - - - Position of %1 %2 set from "%3" to "%4". - - - - - Position of %1 set from %2 to %3. - - - - - prop - - - expression - - - - - definitionDomain - - - - - destinationDomain - - - - - - - - - - - - - - labelPosition - - - - - displayMode - - - - - - - - - - - labelX - - - - - - drawPoints - - - - - - drawDashedLines - - - - - - om_0 - - - - - pass - - - - - gain - - - - - omGraduation - - - - - phase - - - - - unit - - - - - - - x - - - - - - y - - - - - pointStyle - - - - - probabilities - - - - - text - - - - - disableLatex - - - - - targetElement - - - - - approximate - - - - - rounding - - - - - displayStyle - - - - - targetValuePosition - - - - - defaultExpression - - - - - baseValues - - - repartition - Repartition Distribusjon - Repartition functions Distribusjonsfunksjoner @@ -1525,21 +1178,17 @@ Please make sure your latex installation is correct and report a bug if so. sequence - Sequence Følge - Sequences - Følger + Følger sommegainsbode - - Bode Magnitudes Sum Bode-magnitudesum @@ -1547,8 +1196,6 @@ Please make sure your latex installation is correct and report a bug if so. sommephasesbode - - Bode Phases Sum Bode-fasesum @@ -1556,12 +1203,10 @@ Please make sure your latex installation is correct and report a bug if so. text - Text Tekst - Texts Tekster @@ -1574,7 +1219,7 @@ Please make sure your latex installation is correct and report a bug if so.En ny versjon av LogartimePlotter (v{}) er tilgjengelig - + No update available. Ingen nye versjoner. @@ -1592,36 +1237,36 @@ Please make sure your latex installation is correct and report a bug if so. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) @@ -1629,29 +1274,23 @@ Please make sure your latex installation is correct and report a bug if so. visibility - - %1 %2 shown. - %1 %2 vist. + %1 %2 vist. - - %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. xcursor - X Cursor - X-peker + X-peker - X Cursors - X-pekere + X-pekere diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 2cbbff2..b88fc2e 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -4,8 +4,8 @@ About + - About LogarithmPlotter @@ -33,147 +33,147 @@ AppMenuBar - + &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Create - + &Settings - + Check for updates on startup - + Reset redo stack automaticly - + Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -216,42 +216,42 @@ Dialog - + Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value @@ -259,32 +259,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -305,68 +305,68 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done @@ -405,62 +405,62 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - + Objects - + Settings - + History - + Saved plot to '%1'. - + Loading file '%1'. - + Unknown object type: %1. - + Invalid file provided. - + Could not save file: - + Loaded file '%1'. - + Copied plot screenshot to clipboard! - + &Update - + &Update LogarithmPlotter @@ -468,7 +468,7 @@ These settings can be changed at any time from the "Settings" menu. ObjectCreationGrid - + + Create new: @@ -481,7 +481,7 @@ These settings can be changed at any time from the "Settings" menu. - + Show all %1 @@ -489,27 +489,27 @@ These settings can be changed at any time from the "Settings" menu. ObjectRow - + Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 @@ -517,37 +517,37 @@ These settings can be changed at any time from the "Settings" menu. PickLocationOverlay - + Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) @@ -756,251 +756,173 @@ These settings can be changed at any time from the "Settings" menu. - - color - - - - %1 %2's color changed from %3 to %4. - - - - - comment - - - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - - - - - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - - - - - Note: Specify the probability for each value. - - - - - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - - - - - If you have latex enabled, you can use use latex markup in between $$ to create equations. - - - control - + - + %1: - - create - - - - New %1 %2 created. - - - - - delete - - - - %1 %2 deleted. - - - - - editproperty - - - %1 of %2 %3 changed from "%4" to "%5". - - - - - %1 of %2 changed from %3 to %4. - - - error - - + + Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - - - + + + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - - + + Illegal escape sequence: %1. - - + + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - - + + Function %1 must have at least one argument. - - + First argument to map is not a function. - - + Second argument to map is not an array. - - + First argument to fold is not a function. - - + Second argument to fold is not an array. - - - + First argument to filter is not a function. - - - + Second argument to filter is not an array. - - + Second argument to indexOf is not a string or array. - - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1008,7 +930,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1019,13 +941,13 @@ Undoing last change. expression - - + + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1033,49 +955,11 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error - - function - - - Function - - - - - Functions - - - - - gainbode - - - Bode Magnitude - - - - - Bode Magnitudes - - - - - - low-pass - - - - - - high-pass - - - latex @@ -1091,7 +975,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1100,7 +984,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1109,381 +993,22 @@ Please make sure your latex installation is correct and report a bug if so. - name + main - - - %1 %2 renamed to %3. - - - - - parameters - - - above + + Could not open file "{}": +{} - - below + + Could not open file: "{}" +File does not exist. - - - left - - - - - - right - - - - - above-left - - - - - above-right - - - - - below-left - - - - - below-right - - - - - center - - - - - top - - - - - bottom - - - - - top-left - - - - - top-right - - - - - bottom-left - - - - - bottom-right - - - - - application - - - - - function - - - - - high - - - - - low - - - - - Next to target - - - - - With label - - - - - Hidden - - - - - phasebode - - - Bode Phase - - - - - Bode Phases - - - - - point - - - Point - - - - - Points - - - - - position - - - Position of %1 %2 set from "%3" to "%4". - - - - - Position of %1 set from %2 to %3. - - - - - prop - - - expression - - - - - definitionDomain - - - - - destinationDomain - - - - - - - - - - - - - - labelPosition - - - - - displayMode - - - - - - - - - - - labelX - - - - - - drawPoints - - - - - - drawDashedLines - - - - - - om_0 - - - - - pass - - - - - gain - - - - - omGraduation - - - - - phase - - - - - unit - - - - - - - x - - - - - - y - - - - - pointStyle - - - - - probabilities - - - - - text - - - - - disableLatex - - - - - targetElement - - - - - approximate - - - - - rounding - - - - - displayStyle - - - - - targetValuePosition - - - - - defaultExpression - - - - - baseValues - - - - - repartition - - - Repartition - - - - - Repartition functions - - - - - sequence - - - Sequence - - - - - Sequences - - - - - sommegainsbode - - - - Bode Magnitudes Sum - - - - - sommephasesbode - - - - Bode Phases Sum - - - - - text - - - Text - - - - - Texts + + Built with PySide6 (Qt) v{} and python v{} @@ -1495,7 +1020,7 @@ Please make sure your latex installation is correct and report a bug if so. - + No update available. @@ -1513,66 +1038,38 @@ Please make sure your latex installation is correct and report a bug if so. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - - visibility - - - - %1 %2 shown. - - - - - - %1 %2 hidden. - - - - - xcursor - - - X Cursor - - - - - X Cursors - - - diff --git a/LogarithmPlotter/i18n/update.sh b/LogarithmPlotter/i18n/update.sh index aa48415..b8c4716 100755 --- a/LogarithmPlotter/i18n/update.sh +++ b/LogarithmPlotter/i18n/update.sh @@ -1,2 +1,2 @@ #!/bin/bash -lupdate -extensions js,qs,qml,py -recursive .. -ts lp_*.ts +lupdate -extensions mjs,js,qs,qml,py -recursive .. -ts lp_*.ts diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 1071c81..28affed 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -112,6 +112,7 @@ def run(): global tmpfile helper = Helper(pwd, tmpfile) latex = Latex(tempdir) + engine.globalObject().setProperty('Runtime', engine.newObject()) engine.rootContext().setContextProperty("Helper", helper) engine.rootContext().setContextProperty("Latex", latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 7a33bce..a77de0c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -20,9 +20,7 @@ import QtQuick import Qt.labs.platform as Native //import QtQuick.Controls 2.15 import eu.ad5001.MixedMenu 1.1 -import "js/objects.js" as Objects -import "js/historylib.js" as HistoryLib -import "js/math/latex.js" as LatexJS +import "js/historylib.mjs" as HistoryLib /*! @@ -105,17 +103,17 @@ MenuBar { title: qsTr("&Create") // Services repeater Repeater { - model: Object.keys(Objects.types) + model: Object.keys(Runtime.Objects.types) MenuItem { - text: Objects.types[modelData].displayType() - visible: Objects.types[modelData].createable() + text: Runtime.Objects.types[modelData].displayType() + visible: Runtime.Objects.types[modelData].createable() height: visible ? implicitHeight : 0 icon.name: modelData icon.source: './icons/objects/' + modelData + '.svg' icon.color: sysPalette.buttonText onTriggered: { - var newObj = Objects.createNewRegisteredObject(modelData) + var newObj = Runtime.Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() } @@ -153,7 +151,7 @@ MenuBar { checked: Helper.getSettingBool("enable_latex") onTriggered: { Helper.setSettingBool("enable_latex", checked) - LatexJS.enabled = checked + Runtime.Latex.enabled = checked drawCanvas.requestPaint() } icon.name: 'Expression' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index df9503d..8a9a6ba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -19,9 +19,7 @@ import QtQuick import QtQml import QtQuick.Window -import "../js/objects.js" as Objects -import "../js/historylib.js" as HistoryLib -import "../js/history/common.js" as HistoryCommon +import "../js/historylib.mjs" as HistoryLib /*! \qmltype History @@ -214,8 +212,8 @@ Item { } Component.onCompleted: { - HistoryLib.history = historyObj - HistoryCommon.themeTextColor = sysPalette.windowText - HistoryCommon.imageDepth = Screen.devicePixelRatio + Runtime.History.history = historyObj + Runtime.History.themeTextColor = sysPalette.windowText + Runtime.History.imageDepth = Screen.devicePixelRatio } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml index 69ddfdb..b7a79c8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryBrowser.qml @@ -19,7 +19,7 @@ import QtQuick.Controls import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/utils.js" as Utils +import "../js/utils.mjs" as Utils /*! diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml index 041ddfa..3e9b906 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/HistoryItem.qml @@ -19,7 +19,7 @@ import QtQuick.Controls import QtQuick import Qt5Compat.GraphicalEffects -import "../js/utils.js" as Utils +import "../js/utils.mjs" as Utils import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 64bef06..908bdb6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -18,9 +18,8 @@ import QtQuick import Qt.labs.platform as Native -import "js/objects.js" as Objects -import "js/utils.js" as Utils -import "js/mathlib.js" as MathLib +import "js/utils.mjs" as Utils +import "js/mathlib.mjs" as MathLib /*! \qmltype LogGraphCanvas @@ -190,8 +189,8 @@ Canvas { drawAxises(ctx) drawLabels(ctx) ctx.lineWidth = linewidth - for(var objType in Objects.currentObjects) { - for(var obj of Objects.currentObjects[objType]){ + for(var objType in Runtime.Objects.currentObjects) { + for(var obj of Runtime.Objects.currentObjects[objType]){ ctx.strokeStyle = obj.color ctx.fillStyle = obj.color if(obj.visible) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 5b77730..1715967 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -21,11 +21,10 @@ import QtQuick.Controls import eu.ad5001.MixedMenu 1.1 import QtQuick.Layouts 1.12 import QtQuick -// Auto loading all objects. -import "js/objs/autoload.js" as ALObjects -import "js/objects.js" as Objects -import "js/math/latex.js" as LatexJS +// Auto loading all modules. +import "js/modules.js" as Modules + import eu.ad5001.LogarithmPlotter.History 1.0 import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup @@ -50,9 +49,9 @@ ApplicationWindow { Component.onCompleted: { // LatexJS initialization. - LatexJS.enabled = Helper.getSettingBool("enable_latex") - LatexJS.Renderer = Latex - LatexJS.defaultColor = sysPalette.windowText + Runtime.Latex.enabled = Helper.getSettingBool("enable_latex") + Runtime.Latex.Renderer = Latex + Runtime.Latex.defaultColor = sysPalette.windowText } } SystemPalette { id: sysPaletteIn; colorGroup: SystemPalette.Disabled } @@ -201,9 +200,9 @@ ApplicationWindow { filename += '.lpf' settings.saveFilename = filename var objs = {} - for(var objType in Objects.currentObjects){ + for(var objType in Runtime.Objects.currentObjects){ objs[objType] = [] - for(var obj of Objects.currentObjects[objType]) { + for(var obj of Runtime.Objects.currentObjects[objType]) { objs[objType].push(obj.export()) } } @@ -265,19 +264,19 @@ ApplicationWindow { root.width = data["width"] // Importing objects - Objects.currentObjects = {} - Object.keys(Objects.currentObjectsByName).forEach(key => { - delete Objects.currentObjectsByName[key]; + Runtime.Objects.currentObjects = {} + Runtime.Object.keys(Objects.currentObjectsByName).forEach(key => { + delete Runtime.Objects.currentObjectsByName[key]; // Required to keep the same reference for the copy of the object used in expression variable detection. // Another way would be to change the reference as well, but I feel like the code would be less clean. }) for(let objType in data['objects']) { - if(Object.keys(Objects.types).indexOf(objType) > -1) { - Objects.currentObjects[objType] = [] + if(Object.keys(Runtime.Objects.types).indexOf(objType) > -1) { + Runtime.Objects.currentObjects[objType] = [] for(let objData of data['objects'][objType]) { - let obj = new Objects.types[objType](...objData) - Objects.currentObjects[objType].push(obj) - Objects.currentObjectsByName[obj.name] = obj + let obj = new Runtime.Objects.types[objType](...objData) + Runtime.Objects.currentObjects[objType].push(obj) + Runtime.Objects.currentObjectsByName[obj.name] = obj } } else { error += qsTr("Unknown object type: %1.").arg(objType) + "\n"; @@ -285,8 +284,8 @@ ApplicationWindow { } // Updating object dependencies. - for(let objName in Objects.currentObjectsByName) - Objects.currentObjectsByName[objName].update() + for(let objName in Runtime.Objects.currentObjectsByName) + Runtime.Objects.currentObjectsByName[objName].update() // Importing history if("history" in data) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index 3f2f5ab..eb163f3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -20,10 +20,9 @@ import QtQuick import QtQuick.Controls import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../../js/objects.js" as Objects -import "../../js/historylib.js" as HistoryLib -import "../../js/utils.js" as Utils -import "../../js/mathlib.js" as MathLib +import "../../js/historylib.mjs" as HistoryLib +import "../../js/utils.mjs" as Utils +import "../../js/mathlib.mjs" as MathLib /*! \qmltype CustomPropertyList @@ -188,8 +187,8 @@ Repeater { // Base, untranslated version of the model. property var baseModel: selectObjMode ? - Objects.getObjectsName(propertyType.objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Objects.types[propertyType.objType].displayType())] : []) + Runtime.Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Runtime.Objects.types[propertyType.objType].displayType())] : []) : propertyType.values // Translated version of the model. model: selectObjMode ? baseModel : propertyType.translatedValues @@ -199,20 +198,20 @@ Repeater { if(selectObjMode) { // This is only done when what we're selecting are Objects. // Setting object property. - var selectedObj = Objects.currentObjectsByName[baseModel[newIndex]] + var selectedObj = Runtime.Objects.currentObjectsByName[baseModel[newIndex]] if(newIndex != 0) { // Make sure we don't set the object to null. if(selectedObj == null) { // Creating new object. - selectedObj = Objects.createNewRegisteredObject(propertyType.objType) + selectedObj = Runtime.Objects.createNewRegisteredObject(propertyType.objType) history.addToHistory(new HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export())) - baseModel = Objects.getObjectsName(propertyType.objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Objects.types[propertyType.objType].displayType())] : + baseModel = Runtime.Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Runtime.Objects.types[propertyType.objType].displayType())] : []) currentIndex = baseModel.indexOf(selectedObj.name) } - selectedObj.requiredBy.push(Objects.currentObjects[objType][objIndex]) - //Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) + selectedObj.requiredBy.push(Runtime.Objects.currentObjects[objType][objIndex]) + //Runtime.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) } obj.requiredBy = obj.requiredBy.filter((obj) => obj.name != obj.name) history.addToHistory(new HistoryLib.EditedProperty( @@ -256,7 +255,7 @@ Repeater { obj.name, objType, propertyName, obj[propertyName], exported )) - //Objects.currentObjects[objType][objIndex][propertyName] = exported + //Runtime.Objects.currentObjects[objType][objIndex][propertyName] = exported obj[propertyName] = exported root.changed() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 78efdae..2c2b9d0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -22,11 +22,9 @@ import QtQuick.Dialogs as D import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "../../js/objects.js" as Objects -import "../../js/objs/common.js" as ObjectsCommons -import "../../js/historylib.js" as HistoryLib -import "../../js/utils.js" as Utils -import "../../js/mathlib.js" as MathLib +import "../../js/historylib.mjs" as HistoryLib +import "../../js/utils.mjs" as Utils +import "../../js/mathlib.mjs" as MathLib /*! \qmltype Dialog @@ -54,7 +52,7 @@ Popup.BaseDialog { \qmlproperty var EditorDialog::obj Instance of the object being edited. */ - property var obj: Objects.currentObjects[objType][objIndex] + property var obj: Runtime.Objects.currentObjects[objType][objIndex] /*! \qmlproperty var EditorDialog::posPicker Reference to the global PositionPicker QML object. @@ -87,7 +85,7 @@ Popup.BaseDialog { Label { id: dlgTitle verticalAlignment: TextInput.AlignVCenter - text: qsTr("Edit properties of %1 %2").arg(Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) + text: qsTr("Edit properties of %1 %2").arg(Runtime.Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) font.pixelSize: 20 color: sysPalette.windowText } @@ -113,14 +111,14 @@ Popup.BaseDialog { onChanged: function(newValue) { let newName = Utils.parseName(newValue) if(newName != '' && objEditor.obj.name != newName) { - if(newName in Objects.currentObjectsByName) { + if(newName in Runtime.Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) } else { history.addToHistory(new HistoryLib.NameChanged( objEditor.obj.name, objEditor.objType, newName )) - Objects.renameObject(obj.name, newName) - objEditor.obj = Objects.currentObjects[objEditor.objType][objEditor.objIndex] + Runtime.Objects.renameObject(obj.name, newName) + objEditor.obj = Runtime.Objects.currentObjects[objEditor.objType][objEditor.objIndex] objectListList.update() } } @@ -165,7 +163,7 @@ Popup.BaseDialog { */ function open() { dlgCustomProperties.model = [] // Reset - let objProps = Objects.types[objEditor.objType].properties() + let objProps = Runtime.Objects.types[objEditor.objType].properties() dlgCustomProperties.model = Object.keys(objProps).map(prop => [prop, objProps[prop]]) // Converted to 2-dimentional array. objEditor.show() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 1fd7364..6fd42c9 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -18,8 +18,7 @@ import QtQuick import QtQuick.Controls -import "../js/objects.js" as Objects -import "../js/historylib.js" as HistoryLib +import "../js/historylib.mjs" as HistoryLib import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting @@ -44,7 +43,7 @@ Column { // Open editor objectEditor.obj = obj objectEditor.objType = obj.type - objectEditor.objIndex = Objects.currentObjects[obj.type].indexOf(obj) + objectEditor.objIndex = Runtime.Objects.currentObjects[obj.type].indexOf(obj) objectEditor.open() // Disconnect potential link posPicker.picked.disconnect(openEditorDialog) @@ -61,12 +60,12 @@ Column { width: parent.width columns: 3 Repeater { - model: Object.keys(Objects.types) + model: Object.keys(Runtime.Objects.types) Button { id: createBtn width: 96 - visible: Objects.types[modelData].createable() + visible: Runtime.Objects.types[modelData].createable() height: visible ? width*0.8 : 0 // The KDE SDK is kinda buggy, so it respects neither specified color nor display propreties. //display: AbstractButton.TextUnderIcon @@ -94,7 +93,7 @@ Column { anchors.rightMargin: 4 horizontalAlignment: Text.AlignHCenter font.pixelSize: 14 - text: Objects.types[modelData].displayType() + text: Runtime.Objects.types[modelData].displayType() wrapMode: Text.WordWrap clip: true } @@ -104,7 +103,7 @@ Column { ToolTip.text: label.text onClicked: { - let newObj = Objects.createNewRegisteredObject(modelData) + let newObj = Runtime.Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index e7d7a6f..f7d9e27 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -21,7 +21,6 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.ObjectLists.Editor 1.0 as Editor -import "../js/objects.js" as Objects /*! \qmltype ObjectLists @@ -47,7 +46,7 @@ ScrollView { ListView { id: objectsListView - model: Object.keys(Objects.types) + model: Object.keys(Runtime.Objects.types) //width: implicitWidth //objectListList.width - (implicitHeight > objectListList.parent.height ? 20 : 0) implicitHeight: contentItem.childrenRect.height + footerItem.height + 10 @@ -55,7 +54,7 @@ ScrollView { id: objTypeList property string objType: objectsListView.model[index] property var editingRows: [] - model: Objects.currentObjects[objType] + model: Runtime.Objects.currentObjects[objType] width: objectsListView.width implicitHeight: contentItem.childrenRect.height visible: model != undefined && model.length > 0 @@ -70,21 +69,23 @@ ScrollView { CheckBox { id: typeVisibilityCheckBox - checked: Objects.currentObjects[objType] != undefined ? Objects.currentObjects[objType].every(obj => obj.visible) : true + checked: Runtime.Objects.currentObjects[objType] != undefined ? Runtime.Objects.currentObjects[objType].every(obj => obj.visible) : true onClicked: { - for(var obj of Objects.currentObjects[objType]) obj.visible = this.checked + for(var obj of Runtime.Objects.currentObjects[objType]) obj.visible = this.checked for(var obj of objTypeList.editingRows) obj.objVisible = this.checked objectListList.changed() } ToolTip.visible: hovered - ToolTip.text: checked ? qsTr("Hide all %1").arg(Objects.types[objType].displayTypeMultiple()) : qsTr("Show all %1").arg(Objects.types[objType].displayTypeMultiple()) + ToolTip.text: checked ? + qsTr("Hide all %1").arg(Runtime.Objects.types[objType].displayTypeMultiple()) : + qsTr("Show all %1").arg(Runtime.Objects.types[objType].displayTypeMultiple()) } Label { id: typeHeaderText verticalAlignment: TextInput.AlignVCenter - text: qsTranslate("control", "%1: ").arg(Objects.types[objType].displayTypeMultiple()) + text: qsTranslate("control", "%1: ").arg(Runtime.Objects.types[objType].displayTypeMultiple()) font.pixelSize: 20 } } @@ -92,11 +93,11 @@ ScrollView { delegate: ObjectRow { id: controlRow width: objTypeList.width - obj: Objects.currentObjects[objType][index] + obj: Runtime.Objects.currentObjects[objType][index] posPicker: positionPicker onChanged: { - obj = Objects.currentObjects[objType][index] + obj = Runtime.Objects.currentObjects[objType][index] objectListList.update() } @@ -128,7 +129,7 @@ ScrollView { function update() { objectListList.changed() for(var objType in objectListList.listViews) { - objectListList.listViews[objType].model = Objects.currentObjects[objType] + objectListList.listViews[objType].model = Runtime.Objects.currentObjects[objType] } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index ab3f2f7..cdd9e3a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -21,9 +21,7 @@ import QtQuick.Dialogs import QtQuick.Controls import QtQuick.Window import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/objects.js" as Objects -import "../js/historylib.js" as HistoryLib -import "../js/math/latex.js" as LatexJS +import "../js/historylib.mjs" as HistoryLib /*! @@ -91,16 +89,16 @@ Item { id: objDescription anchors.left: objVisibilityCheckBox.right anchors.right: deleteButton.left - height: LatexJS.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight + height: Runtime.Latex.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight verticalAlignment: TextInput.AlignVCenter - text: LatexJS.enabled ? "" : obj.getReadableString() + text: Runtime.Latex.enabled ? "" : obj.getReadableString() font.pixelSize: 14 Image { id: latexDescription anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - visible: LatexJS.enabled + visible: Runtime.Latex.enabled property double depth: Screen.devicePixelRatio property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color).split(",") : ["","0","0"] source: visible ? ltxInfo[0] : "" @@ -111,7 +109,7 @@ Item { MouseArea { anchors.fill: parent onClicked: { - objEditor.obj = Objects.currentObjects[obj.type][index] + objEditor.obj = Runtime.Objects.currentObjects[obj.type][index] objEditor.objType = obj.type objEditor.objIndex = index //objEditor.editingRow = objectRow @@ -213,10 +211,14 @@ Item { function deleteRecursively(object) { for(let toRemove of object.requiredBy) deleteRecursively(toRemove) - object.requiredBy = [] - history.addToHistory(new HistoryLib.DeleteObject( - object.name, object.type, object.export() - )) - Objects.deleteObject(object.name) + if(Runtime.Objects.currentObjectsByName[object.name] != undefined) { + // Object still exists + // Temporary fix for objects require not being propertly updated. + object.requiredBy = [] + history.addToHistory(new HistoryLib.DeleteObject( + object.name, object.type, object.export() + )) + Runtime.Objects.deleteObject(object.name) + } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index afc8d61..c92182a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -19,9 +19,8 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/objects.js" as Objects -import "js/mathlib.js" as MathLib -import "js/historylib.js" as HistoryLib +import "js/mathlib.mjs" as MathLib +import "js/historylib.mjs" as HistoryLib /*! \qmltype PickLocationOverlay @@ -114,7 +113,7 @@ Item { if(mouse.button == Qt.LeftButton) { // Validate let newValueX = !parent.userPickX ? null : parseValue(picked.mouseX.toString(), objType, propertyX) let newValueY = !parent.userPickY ? null : parseValue(picked.mouseY.toString(), objType, propertyY) - let obj = Objects.currentObjectsByName[objName] + let obj = Runtime.Objects.currentObjectsByName[objName] // Set values if(parent.userPickX && parent.userPickY) { history.addToHistory(new HistoryLib.EditedPosition( @@ -324,7 +323,7 @@ Item { Parses a given \c value as an expression or a number depending on the type of \c propertyName of all \c objType. */ function parseValue(value, objType, propertyName) { - if(Objects.types[objType].properties()[propertyName] == 'number') + if(Runtime.Objects.types[objType].properties()[propertyName] == 'number') return parseFloat(value) else return new MathLib.Expression(value) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index dddafab..9ddfa0f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -18,7 +18,6 @@ import QtQuick import QtQuick.Controls -import "../js/math/latex.js" as Latex /*! \qmltype GreetScreen diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index fa3dece..be5160b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -20,10 +20,9 @@ import QtQuick.Controls import QtQuick import Qt.labs.platform as Native import eu.ad5001.LogarithmPlotter.Popup 1.0 as P -import "../js/mathlib.js" as MathLib -import "../js/utils.js" as Utils -import "../js/objects.js" as Objects -import "../js/parsing/parsing.js" as Parsing +import "../js/mathlib.mjs" as MathLib +import "../js/utils.mjs" as Utils +import "../js/parsing/parsing.mjs" as Parsing /*! @@ -392,9 +391,9 @@ Item { property string objectName: isEnteringProperty ? (parent.currentToken.dot ? parent.previousToken.value : parent.previousToken2.value) : "" - property bool doesObjectExist: isEnteringProperty && (objectName in Objects.currentObjectsByName) + property bool doesObjectExist: isEnteringProperty && (objectName in Runtime.Objects.currentObjectsByName) property var objectProperties: doesObjectExist ? - Objects.currentObjectsByName[objectName].constructor.properties() : + Runtime.Objects.currentObjectsByName[objectName].constructor.properties() : {} categoryItems: Object.keys(objectProperties) autocompleteGenerator: (item) => { @@ -461,9 +460,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: functionsList.itemStartIndex + functionsList.model.length itemSelected: parent.itemSelected - categoryItems: Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) + categoryItems: Runtime.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), + 'text': item, 'annotation': Runtime.Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), 'autocomplete': item+'()', 'cursorFinalOffset': -1 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -476,9 +475,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: executableObjectsList.itemStartIndex + executableObjectsList.model.length itemSelected: parent.itemSelected - categoryItems: Object.keys(Objects.currentObjectsByName).filter(obj => obj != self) + categoryItems: Object.keys(Runtime.Objects.currentObjectsByName).filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': `${Objects.currentObjectsByName[item].constructor.displayType()}`, + 'text': item, 'annotation': `${Runtime.Objects.currentObjectsByName[item].constructor.displayType()}`, 'autocomplete': item+'.', 'cursorFinalOffset': 0 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -538,8 +537,8 @@ Item { throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) // Recursive dependencies let dependentOnSelfObjects = expr.requiredObjects().filter( - (obj) => Objects.currentObjectsByName[obj].getDependenciesList() - .includes(Objects.currentObjectsByName[control.self]) + (obj) => Runtime.Objects.currentObjectsByName[obj].getDependenciesList() + .includes(Runtime.Objects.currentObjectsByName[control.self]) ) if(dependentOnSelfObjects.length == 1) throw new Error(qsTranslate('error', 'Circular dependency detected. Object %1 depends on %2.').arg(dependentOnSelfObjects[0].toString()).arg(control.self)) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 208e3e9..2c50c56 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -16,11 +16,11 @@ * along with this program. If not, see . */ +import QtQuick import QtQuick.Controls -import QtQuick import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting import eu.ad5001.LogarithmPlotter.Popup 1.0 as Popup -import "js/utils.js" as Utils +import "js/utils.mjs" as Utils /*! \qmltype Settings diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index 0d80da4..85b461e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -19,9 +19,8 @@ import QtQuick import QtQuick.Controls import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "js/objects.js" as Objects -import "js/mathlib.js" as MathLib -import "js/historylib.js" as HistoryLib +import "js/mathlib.mjs" as MathLib +import "js/historylib.mjs" as HistoryLib /*! \qmltype ViewPositionChangeOverlay diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs similarity index 93% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs index 9f921b5..c8bb577 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/color.mjs @@ -16,13 +16,10 @@ * along with this program. If not, see . */ -.pragma library +import EditedProperty from "editproperty.mjs" +import Objects from "../objects.mjs" -.import "editproperty.js" as EP -.import "../objects.js" as Objects - - -class ColorChanged extends EP.EditedProperty { +export default class ColorChanged extends EditedProperty { // Action used everytime when an object's color is changed type(){return 'ColorChanged'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs similarity index 72% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 2baf532..d9a3bc8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -16,16 +16,29 @@ * along with this program. If not, see . */ -.pragma library - -.import "../math/latex.js" as Latex - -var themeTextColor; -var imageDepth = 2; -var fontSize = 14; +import { RuntimeAPI } from "../runtime.mjs" +import Latex from "../math/latex.mjs" -class Action { +class HistoryCommonAPI extends RuntimeAPI { + constructor() { + super('History', [ + Runtime.Latex + ]) + // History QML object + this.history = null; + this.themeTextColor = "#ff0000"; + this.imageDepth = 2; + this.fontSize = 14; + } +} + +/** @type {HistoryCommonAPI} */ +Runtime.History = Runtime.History || new HistoryCommonAPI() + +export const API = Runtime.History + +export class Action { /** * Type of the action. * @@ -48,15 +61,11 @@ class Action { /** * Undoes the action. - * - * @returns {string} */ undo() {} /** * Redoes the action. - * - * @returns {string} */ redo() {} @@ -64,7 +73,7 @@ class Action { * Export the action to a serializable format. * NOTE: These arguments will be reinputed in the constructor in this order. * - * @returns {string} + * @returns {string[]} */ export() { return [this.targetName, this.targetType] @@ -86,7 +95,7 @@ class Action { * @returns {string} */ getIconRichText(type) { - return `` + return `` } /** @@ -98,8 +107,13 @@ class Action { renderLatexAsHtml(latexString) { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") - let latexInfo = Latex.Renderer.render(latexString, imageDepth*(fontSize+2), themeTextColor).split(",") - return `` + let imgDepth = Runtime.History.imageDepth + let [src, width, height] = Latex.Renderer.render( + latexString, + imgDepth * (Runtime.History.fontSize + 2), + Runtime.History.themeTextColor + ).split(",") + return `` } /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs similarity index 81% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs index 8eca385..e474133 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/create.mjs @@ -16,12 +16,10 @@ * along with this program. If not, see . */ -.pragma library +import Objects from "../objects.mjs" +import { Action } from "common.mjs" -.import "../objects.js" as Objects -.import "common.js" as C - -class CreateNewObject extends C.Action { +export default class CreateNewObject extends Action { // Action used for the creation of an object type(){return 'CreateNewObject'} @@ -37,10 +35,6 @@ class CreateNewObject extends C.Action { undo() { Objects.deleteObject(this.targetName) - //let targetIndex = Objects.getObjectsName(this.targetType).indexOf(this.targetName) - //delete Objects.currentObjectsByName[this.targetName] - //Objects.currentObjects[this.targetType][targetIndex].delete() - //Objects.currentObjects[this.targetType].splice(targetIndex, 1) } redo() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs similarity index 83% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs index c70d2d0..ea1deb1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/delete.mjs @@ -16,14 +16,14 @@ * along with this program. If not, see . */ -.pragma library - -.import "../objects.js" as Objects -.import "create.js" as Create +import Objects from "../objects.mjs" +import CreateNewObject from "create.mjs" -class DeleteObject extends Create.CreateNewObject { - // Action used at the deletion of an object. Basicly the same thing as creating a new object, except Redo & Undo are reversed. +export default class DeleteObject extends CreateNewObject { + /** + * Action used at the deletion of an object. Basically the same thing as creating a new object, except Redo & Undo are reversed. + */ type(){return 'DeleteObject'} icon(){return 'delete'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs similarity index 86% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs index 9b712f2..3540cfe 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/editproperty.mjs @@ -16,15 +16,13 @@ * along with this program. If not, see . */ -.pragma library +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" +import * as MathLib from "../mathlib.mjs" +import { Action } from "common.mjs" +import { DrawableObject } from "../objs/common.mjs" -.import "../objects.js" as Objects -.import "../math/latex.js" as Latex -.import "../mathlib.js" as MathLib -.import "../objs/common.js" as Common -.import "common.js" as C - -class EditedProperty extends C.Action { +export default class EditedProperty extends Action { // Action used everytime an object's property has been changed type(){return 'EditedProperty'} @@ -33,7 +31,16 @@ class EditedProperty extends C.Action { color(darkVer=false){ return darkVer ? 'darkslateblue' : 'cyan'; } - + + /** + * + * @param {string} targetName - Name of the object to target + * @param {string} targetType - Type of the object to target. + * @param {string} targetProperty - Property being changed + * @param {any} previousValue - Previous value before change + * @param {any} newValue - New value after change + * @param {boolean} valueIsExpressionNeedingImport - True if the value needs to be imported. (e.g expressions) + */ constructor(targetName = "", targetType = "Point", targetProperty = "visible", previousValue = false, newValue = true, valueIsExpressionNeedingImport = false) { super(targetName, targetType) this.targetProperty = targetProperty @@ -42,10 +49,10 @@ class EditedProperty extends C.Action { this.newValue = newValue this.propertyType = Objects.types[targetType].properties()[targetProperty] if(valueIsExpressionNeedingImport) { - if(typeof this.propertyType == 'object' && this.propertyType.type == "Expression") { + if(typeof this.propertyType == 'object' && this.propertyType.type === "Expression") { this.previousValue = new MathLib.Expression(this.previousValue); this.newValue = new MathLib.Expression(this.newValue); - } else if(this.propertyType == "Domain") { + } else if(this.propertyType === "Domain") { this.previousValue = MathLib.parseDomain(this.previousValue); this.newValue = MathLib.parseDomain(this.newValue); } else { @@ -70,7 +77,7 @@ class EditedProperty extends C.Action { export() { if(this.previousValue instanceof MathLib.Expression) { return [this.targetName, this.targetType, this.targetProperty, this.previousValue.toEditableString(), this.newValue.toEditableString(), true] - } else if(this.previousValue instanceof Common.DrawableObject) { + } else if(this.previousValue instanceof DrawableObject) { return [this.targetName, this.targetType, this.targetProperty, this.previousValue.name, this.newValue.name, true] } else { return [this.targetName, this.targetType, this.targetProperty, this.previousValue, this.newValue, false] @@ -110,7 +117,7 @@ class EditedProperty extends C.Action { // HTML this.prevHTML = ' '+this.prevString+' ' this.nextHTML = ' '+this.nextString+' ' - if(Latex.enabled && typeof this.propertyType == 'object' && this.propertyType.type == "Expression") { + 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) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs similarity index 83% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs index 89f97c3..7698adf 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/name.mjs @@ -16,19 +16,16 @@ * along with this program. If not, see . */ -.pragma library - -.import "editproperty.js" as EP -.import "../objects.js" as Objects +import EditedProperty from "editproperty.mjs" +import Objects from "../objects.mjs" -class NameChanged extends EP.EditedProperty { +export default class NameChanged extends EditedProperty { // Action used everytime an object's property has been changed type(){return 'NameChanged'} icon(){return 'name'} - - + color(darkVer=false){return darkVer ? 'darkorange' : 'orange'} constructor(targetName = "", targetType = "Point", newName = "") { @@ -45,10 +42,6 @@ class NameChanged extends EP.EditedProperty { redo() { Objects.renameObject(this.previousValue, this.newValue) - //let obj = Objects.currentObjectsByName[this.previousValue] - //obj.name = this.newValue - //Objects.currentObjectsByName[this.newValue] = obj - //delete Objects.currentObjectsByName[this.previousValue] } getReadableString() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs similarity index 89% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs index c171124..eaf4b65 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/position.mjs @@ -16,16 +16,14 @@ * along with this program. If not, see . */ -.pragma library +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" +import * as MathLib from "../mathlib.mjs" +import { escapeHTML } from "../utils.mjs" +import { Action } from "common.mjs" +import { DrawableObject } from "../objs/common.mjs" -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../math/latex.js" as Latex -.import "../utils.js" as Utils -.import "../objs/common.js" as Common -.import "common.js" as C - -class EditedPosition extends C.Action { +export default class EditedPosition extends Action { // Action used for objects that have a X and Y expression properties (points, texts...) type(){return 'EditedPosition'} @@ -68,8 +66,8 @@ class EditedPosition extends C.Action { this.prevHTML = this.renderLatexAsHtml(`\\left(${this.previousXValue.latexMarkup},${this.previousYValue.latexMarkup}\\right)`) this.nextHTML = this.renderLatexAsHtml(`\\left(${this.newXValue.latexMarkup},${this.newYValue.latexMarkup}\\right)`) } else { - this.prevHTML = ' '+Utils.escapeHTML(this.prevString)+' ' - this.nextHTML = ' '+Utils.escapeHTML(this.nextString)+' ' + this.prevHTML = ' '+escapeHTML(this.prevString)+' ' + this.nextHTML = ' '+escapeHTML(this.nextString)+' ' } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs similarity index 92% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs index 78981eb..d38b33f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/visibility.mjs @@ -16,13 +16,11 @@ * along with this program. If not, see . */ -.pragma library - -.import "editproperty.js" as EP -.import "../objects.js" as Objects +import EditedProperty from "editproperty.mjs" +import Objects from "../objects.mjs" -class EditedVisibility extends EP.EditedProperty { +export default class EditedVisibility extends EditedProperty { // Action used when an object's shown or hidden. type(){return 'EditedVisibility'} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs similarity index 66% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs index d9fa812..189d59b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/historylib.mjs @@ -18,30 +18,27 @@ // This library helps containing actions to be undone or redone (in other words, editing history) // Each type of event is repertoried as an action that can be listed for everything that's undoable. -.pragma library -.import "history/common.js" as Common -.import "history/create.js" as Create -.import "history/delete.js" as Delete -.import "history/editproperty.js" as EP -.import "history/position.js" as Pos -.import "history/visibility.js" as V -.import "history/name.js" as Name -.import "history/color.js" as Color - -var history = null; +import { Action as A } from "history/common.mjs" +import Create from "history/create.mjs" +import Delete from "history/delete.mjs" +import EP from "history/editproperty.mjs" +import Pos from "history/position.mjs" +import V from "history/visibility.mjs" +import Name from "history/name.mjs" +import Color from "history/color.mjs" -var Action = Common.Action -var CreateNewObject = Create.CreateNewObject -var DeleteObject = Delete.DeleteObject -var EditedProperty = EP.EditedProperty -var EditedPosition = Pos.EditedPosition -var EditedVisibility = V.EditedVisibility -var NameChanged = Name.NameChanged -var ColorChanged = Color.ColorChanged +export const Action = A +export const CreateNewObject = Create +export const DeleteObject = Delete +export const EditedProperty = EP +export const EditedPosition = Pos +export const EditedVisibility = V +export const NameChanged = Name +export const ColorChanged = Color -var Actions = { +export const Actions = { "Action": Action, "CreateNewObject": CreateNewObject, "DeleteObject": DeleteObject, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/expr-eval.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/expr-eval.js diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js new file mode 100644 index 0000000..68a88c1 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js @@ -0,0 +1,121 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +.pragma library + +.import "expr-eval.js" as ExprEval +.import "../../runtime.mjs" as R + +let RuntimeAPI = R.RuntimeAPI + +const evalVariables = { + // Variables not provided by expr-eval.js, needs to be provided manually + "pi": Math.PI, + "PI": Math.PI, + "π": Math.PI, + "inf": Infinity, + "infinity": Infinity, + "Infinity": Infinity, + "∞": Infinity, + "e": Math.E, + "E": Math.E, + "true": true, + "false": false +} + +class ExprParserAPI extends RuntimeAPI { + constructor() { + super('ExprParser', [ + /** @type {ObjectsAPI} */ + Runtime.Objects + ]) + this.currentVars = {} + this.Internals = ExprEval + this._parser = new ExprEval.Parser() + + this._parser.consts = Object.assign({}, this._parser.consts, evalVariables) + + this._parser.functions.integral = this.integral.bind(this) + this._parser.functions.derivative = this.derivative.bind(this) + } + + /** + * Parses arguments for a function, returns the corresponding JS function if it exists. + * Throws either usage error otherwise. + * @param {array} args - Arguments of the function, either [ ExecutableObject ] or [ string, variable ]. + * @param {string} usage1 - Usage for executable object. + * @param {string} usage2 - Usage for string function. + * @return {function} JS function to call. + */ + parseArgumentsForFunction(args, usage1, usage2) { + let f, target, variable + if(args.length === 1) { + // Parse object + f = args[0] + if(typeof f !== 'object' || !f.execute) + throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage1)) + let target = f + f = (x) => target.execute(x) + } else if(args.length === 2) { + // Parse variable + [f,variable] = args + if(typeof f !== 'string' || typeof variable !== 'string') + throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2)) + f = this._parser.parse(f).toJSFunction(variable, this.currentVars) + } else + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + return f + } + + /** + * @param {string} expression - Expression to parse + */ + parse(expression) { + return this._parser.parse(expression) + } + + integral(a, b, ...args) { + let usage1 = qsTranslate('usage', 'integral(, , )') + let usage2 = qsTranslate('usage', 'integral(, , , )') + let f = this.parseArgumentsForFunction(args, usage1, usage2) + if(a == null || b == null) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + + // https://en.wikipedia.org/wiki/Simpson%27s_rule + // Simpler, faster than tokenizing the expression + return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) + } + + derivative(...args) { + let usage1 = qsTranslate('usage', 'derivative(, )') + let usage2 = qsTranslate('usage', 'derivative(, , )') + let x = args.pop() + let f = this.parseArgumentsForFunction(args, usage1, usage2) + if(x == null) + throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) + + let derivative_precision = x/10 + return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision + } +} + +/** @type {ExprParserAPI} */ +Runtime.ExprParser = Runtime.ExprParser || new ExprParserAPI() + + + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs similarity index 53% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index 8ee04cf..d3214f7 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -1,42 +1,30 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -.pragma library +// Type polyfills for IDEs. +// Never directly imported. -.import "common.js" as C -.import "point.js" as P -.import "text.js" as T -.import "function.js" as F -.import "gainbode.js" as GB -.import "phasebode.js" as PB -.import "sommegainsbode.js" as SGB -.import "sommephasesbode.js" as SPB -.import "xcursor.js" as X -.import "sequence.js" as S -.import "repartition.js" as R - -C.registerObject(P.Point) -C.registerObject(T.Text) -C.registerObject(F.Function) -C.registerObject(GB.GainBode) -C.registerObject(PB.PhaseBode) -C.registerObject(SGB.SommeGainsBode) -C.registerObject(SPB.SommePhasesBode) -C.registerObject(X.XCursor) -C.registerObject(S.Sequence) -C.registerObject(R.RepartitionFunction) +Runtime = Runtime || {} +/** @type {function(string, string): string} */ +qsTranslate = qsTranslate || function(category, string) { throw new Error('qsTranslate not implemented.'); } +/** @type {function(string): string} */ +qsTr = qsTr || function(string) { throw new Error('qsTr not implemented.'); } +/** @type {function(string, string): string} */ +QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); } +/** @type {function(string|boolean|int): string} */ +String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js deleted file mode 100644 index 0858522..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/common.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -.pragma library - -.import "../expr-eval.js" as ExprEval -.import "../utils.js" as Utils -.import "latex.js" as Latex - -var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually - "pi": Math.PI, - "PI": Math.PI, - "π": Math.PI, - "inf": Infinity, - "infinity": Infinity, - "Infinity": Infinity, - "∞": Infinity, - "e": Math.E, - "E": Math.E, - "true": true, - "false": false - -} - -var currentVars = {} -var currentObjectsByName = {} // Mirror of currentObjectsByName in objects.js - -const parser = new ExprEval.Parser() - -parser.consts = Object.assign({}, parser.consts, evalVariables) - -/** - * Parses arguments for a function, returns the corresponding JS function if it exists. - * Throws either usage error otherwise. - * @param {array} args - Arguments of the function, either [ ExecutableObject ] or [ string, variable ]. - * @param {string} usage1 - Usage for executable object. - * @param {string} usage2 - Usage for string function. - * @return {callable} JS function to call.. - */ -function parseArgumentsForFunction(args, usage1, usage2) { - let f, target, variable - if(args.length == 1) { - // Parse object - f = args[0] - if(typeof f != 'object' || !f.execute) - throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage1)) - let target = f - f = (x) => target.execute(x) - } else if(args.length == 2) { - // Parse variable - [f,variable] = args - if(typeof f != 'string' || typeof variable != 'string') - throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2)) - f = parser.parse(f).toJSFunction(variable, currentVars) - } else - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) - return f -} - -// Function definition -parser.functions.integral = function(a, b, ...args) { - let usage1 = qsTranslate('usage', 'integral(, , )') - let usage2 = qsTranslate('usage', 'integral(, , , )') - let f = parseArgumentsForFunction(args, usage1, usage2) - if(a == null || b == null) - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) - - // https://en.wikipedia.org/wiki/Simpson%27s_rule - // Simpler, faster than tokenizing the expression - return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) -} - -parser.functions.derivative = function(...args) { - let usage1 = qsTranslate('usage', 'derivative(, )') - let usage2 = qsTranslate('usage', 'derivative(, , )') - let x = args.pop() - let f = parseArgumentsForFunction(args, usage1, usage2) - if(x == null) - throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)) - - let derivative_precision = x/10 - return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision -} - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs similarity index 79% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs index 6c47a23..e2606c4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/domain.mjs @@ -16,21 +16,19 @@ * along with this program. If not, see . */ -.pragma library - -.import "expression.js" as Expr +import { Expression, executeExpression } from "expression.mjs" /** * Main abstract domain class * It doesn't represent any kind of domain and is meant to be extended. */ -class Domain { +export class Domain { constructor() {} /** * Checks whether x is included in the domain. * @param {number} x - The x value. - * @return {bool} true if included, false otherwise. + * @return {boolean} true if included, false otherwise. */ includes(x) { return false } @@ -166,7 +164,7 @@ class Domain { /** * Represents an empty set. */ -class EmptySet extends Domain { +export class EmptySet extends Domain { constructor() { super() this.displayName = "∅" @@ -187,12 +185,12 @@ class EmptySet extends Domain { /** * Domain classes for ranges (e.g ]0;3[, [1;2[ ...) */ -class Range extends Domain { +export class Range extends Domain { constructor(begin, end, openBegin, openEnd) { super() - if(typeof begin == 'number' || typeof begin == 'string') begin = new Expr.Expression(begin.toString()) + if(typeof begin == 'number' || typeof begin == 'string') begin = new Expression(begin.toString()) this.begin = begin - if(typeof end == 'number' || typeof end == 'string') end = new Expr.Expression(end.toString()) + if(typeof end == 'number' || typeof end == 'string') end = new Expression(end.toString()) this.end = end this.openBegin = openBegin this.openEnd = openEnd @@ -201,7 +199,7 @@ class Range extends Domain { } includes(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) return ((this.openBegin && x > this.begin.execute()) || (!this.openBegin && x >= this.begin.execute())) && ((this.openEnd && x < this.end.execute()) || (!this.openEnd && x <= this.end.execute())) } @@ -229,9 +227,9 @@ class Range extends Domain { } static import(frm) { - var openBegin = frm.trim().charAt(0) == "]" - var openEnd = frm.trim().charAt(frm.length -1) == "[" - var [begin, end] = frm.substr(1, frm.length-2).split(";") + let openBegin = frm.trim().charAt(0) === "]" + let openEnd = frm.trim().charAt(frm.length -1) === "[" + let [begin, end] = frm.substr(1, frm.length-2).split(";") return new Range(begin.trim(), end.trim(), openBegin, openEnd) } } @@ -239,17 +237,16 @@ class Range extends Domain { /** * Domain classes for special domains (N, Z, ...) */ -class SpecialDomain extends Domain { +export class SpecialDomain extends Domain { /** * @constructs SpecialDomain * @param {string} displayName * @param {function} isValid - function returning true when number is in domain false when it isn't. * @param {function} next - function provides the next positive value in the domain after the one given. * @param {function} previous - function provides the previous positive value in the domain before the one given. - * @param {bool} moveSupported - Only true if next and previous functions are valid. - * @param items + * @param {boolean} moveSupported - Only true if next and previous functions are valid. */ - constructor(displayName, isValid, next = x => true, previous = x => true, + constructor(displayName, isValid, next = () => true, previous = () => true, moveSupported = true) { super() this.displayName = displayName @@ -260,17 +257,17 @@ class SpecialDomain extends Domain { } includes(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) return this.isValid(x) } next(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) return this.nextValue(x) } previous(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) return this.prevValue(x) } @@ -300,14 +297,14 @@ class SpecialDomain extends Domain { /** * Domain classes for sets (e.g {0;3}, {0;1;2;pi} ...) */ -class DomainSet extends SpecialDomain { +export class DomainSet extends SpecialDomain { constructor(values) { super('', x => true, x => x, true) - var newVals = {} + let newVals = {} this.executedValues = [] - for(var value of values) { - var expr = new Expr.Expression(value.toString()) - var ex = expr.execute() + for(let value of values) { + let expr = new Expression(value.toString()) + let ex = expr.execute() newVals[ex] = expr this.executedValues.push(ex) } @@ -318,30 +315,30 @@ class DomainSet extends SpecialDomain { } includes(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) - for(var value of this.values) - if(x == value.execute()) return true + if(typeof x == 'string') x = executeExpression(x) + for(let value of this.values) + if(x === value.execute()) return true return false } next(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) if(x < this.executedValues[0]) return this.executedValues[0] - for(var i = 1; i < this.values.length; i++) { - var prevValue = this.executedValues[i-1] - var value = this.executedValues[i] + for(let i = 1; i < this.values.length; i++) { + let prevValue = this.executedValues[i-1] + let value = this.executedValues[i] if(x >= prevValue && x < value) return value } return null } previous(x) { - if(typeof x == 'string') x = Expr.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) if(x > this.executedValues[this.executedValues.length-1]) return this.executedValues[this.executedValues.length-1] - for(var i = 1; i < this.values.length; i++) { - var prevValue = this.executedValues[i-1] - var value = this.executedValues[i] + for(let i = 1; i < this.values.length; i++) { + let prevValue = this.executedValues[i-1] + let value = this.executedValues[i] if(x > prevValue && x <= value) return prevValue } return null @@ -354,56 +351,56 @@ class DomainSet extends SpecialDomain { union(domain) { if(domain instanceof EmptySet) return this if(domain instanceof DomainSet) { - var newValues = [] - var values = this.values.concat(domain.values).filter(function(val){ + let newValues = [] + let values = this.values.concat(domain.values).filter(function(val){ newValues.push(val.execute()) - return newValues.indexOf(val.execute()) == newValues.length - 1 + return newValues.indexOf(val.execute()) === newValues.length - 1 }) return new DomainSet(values) } - var notIncludedValues = [] - for(var value in this.values) { - var value = this.executedValues[i] + let notIncludedValues = [] + for(let i = 0; i < this.values.length; i++) { + let value = this.executedValues[i] if(domain instanceof Range) { - if(domain.begin.execute() == value && domain.openBegin) { + if(domain.begin.execute() === value && domain.openBegin) { domain.openBegin = false } - if(domain.end.execute() == value && domain.openEnd) { + if(domain.end.execute() === value && domain.openEnd) { domain.openEnd = false } } if(!domain.includes(value)) notIncludedValues.push(this.values[i].toEditableString()) } - if(notIncludedValues.length == 0) return domain + if(notIncludedValues.length === 0) return domain return new UnionDomain(domain, new DomainSet(notIncludedValues)) } intersection(domain) { if(domain instanceof EmptySet) return domain if(domain instanceof DomainSet) { - var domValues = domain.values.map(expr => expr.execute()) + let domValues = domain.values.map(expr => expr.execute()) this.values = this.values.filter(function(val){ return domValues.indexOf(val.execute()) >= 0 }) return this } - var includedValues = [] - for(var i in this.values) { - var value = this.executedValues[i] + let includedValues = [] + for(let i in this.values) { + let value = this.executedValues[i] if(domain instanceof Range) { - if(domain.begin.execute() == value && !domain.openBegin) { + if(domain.begin.execute() === value && !domain.openBegin) { domain.openBegin = false } - if(domain.end.execute() == value && !domain.openEnd) { + if(domain.end.execute() === value && !domain.openEnd) { domain.openEnd = false } } if(domain.includes(value)) includedValues.push(this.values[i].toEditableString()) } - if(includedValues.length == 0) return new EmptySet() - if(includedValues.length == this.values.length) return this + if(includedValues.length === 0) return new EmptySet() + if(includedValues.length === this.values.length) return this return new IntersectionDomain(domain, new DomainSet(includedValues)) } @@ -415,7 +412,7 @@ class DomainSet extends SpecialDomain { /** * Domain representing the union between two domains. */ -class UnionDomain extends Domain { +export class UnionDomain extends Domain { constructor(dom1, dom2) { super() this.dom1 = dom1 @@ -450,10 +447,10 @@ class UnionDomain extends Domain { } static import(frm) { - var domains = frm.trim().split("∪") - if(domains.length == 1) domains = frm.trim().split("U") // Fallback - var dom2 = parseDomain(domains.pop()) - var dom1 = parseDomain(domains.join('∪')) + let domains = frm.trim().split("∪") + if(domains.length === 1) domains = frm.trim().split("U") // Fallback + let dom2 = parseDomain(domains.pop()) + let dom1 = parseDomain(domains.join('∪')) return dom1.union(dom2) } } @@ -461,7 +458,7 @@ class UnionDomain extends Domain { /** * Domain representing the intersection between two domains. */ -class IntersectionDomain extends Domain { +export class IntersectionDomain extends Domain { constructor(dom1, dom2) { super() this.dom1 = dom1 @@ -496,9 +493,9 @@ class IntersectionDomain extends Domain { } static import(frm) { - var domains = frm.trim().split("∩") - var dom1 = parseDomain(domains.pop()) - var dom2 = parseDomain(domains.join('∩')) + let domains = frm.trim().split("∩") + let dom1 = parseDomain(domains.pop()) + let dom2 = parseDomain(domains.join('∩')) return dom1.intersection(dom2) } } @@ -506,7 +503,7 @@ class IntersectionDomain extends Domain { /** * Domain representing the minus between two domains. */ -class MinusDomain extends Domain { +export class MinusDomain extends Domain { constructor(dom1, dom2) { super() this.dom1 = dom1 @@ -524,10 +521,10 @@ class MinusDomain extends Domain { } static import(frm) { - var domains = frm.trim().split("∖") - if(domains.length == 1) domains = frm.trim().split("\\") // Fallback - var dom1 = parseDomain(domains.shift()) - var dom2 = parseDomain(domains.join('∪')) + let domains = frm.trim().split("∖") + if(domains.length === 1) domains = frm.trim().split("\\") // Fallback + let dom1 = parseDomain(domains.shift()) + let dom2 = parseDomain(domains.join('∪')) return new MinusDomain(dom1, dom2) } } @@ -551,53 +548,53 @@ Domain.RPE.latexMarkup = "\\mathbb{R}^{+*}" Domain.RME = new Range(-Infinity,0,true,true) Domain.RME.displayName = "ℝ⁻*" Domain.RME.latexMarkup = "\\mathbb{R}^{+*}" -Domain.N = new SpecialDomain('ℕ', x => x%1==0 && x >= 0, +Domain.N = new SpecialDomain('ℕ', x => x%1===0 && x >= 0, x => Math.max(Math.floor(x)+1, 0), x => Math.max(Math.ceil(x)-1, 0)) Domain.N.latexMarkup = "\\mathbb{N}" -Domain.NE = new SpecialDomain('ℕ*', x => x%1==0 && x > 0, +Domain.NE = new SpecialDomain('ℕ*', x => x%1===0 && x > 0, x => Math.max(Math.floor(x)+1, 1), x => Math.max(Math.ceil(x)-1, 1)) Domain.NE.latexMarkup = "\\mathbb{N}^{*}" -Domain.Z = new SpecialDomain('ℤ', x => x%1==0, x => Math.floor(x)+1, x => Math.ceil(x)-1) +Domain.Z = new SpecialDomain('ℤ', x => x%1===0, x => Math.floor(x)+1, x => Math.ceil(x)-1) Domain.Z.latexMarkup = "\\mathbb{Z}" -Domain.ZE = new SpecialDomain('ℤ*', x => x%1==0 && x != 0, - x => Math.floor(x)+1 == 0 ? Math.floor(x)+2 : Math.floor(x)+1, - x => Math.ceil(x)-1 == 0 ? Math.ceil(x)-2 : Math.ceil(x)-1) +Domain.ZE = new SpecialDomain('ℤ*', x => x%1===0 && x !== 0, + x => Math.floor(x)+1 === 0 ? Math.floor(x)+2 : Math.floor(x)+1, + x => Math.ceil(x)-1 === 0 ? Math.ceil(x)-2 : Math.ceil(x)-1) Domain.ZE.latexMarkup = "\\mathbb{Z}^{*}" -Domain.ZM = new SpecialDomain('ℤ⁻', x => x%1==0 && x <= 0, +Domain.ZM = new SpecialDomain('ℤ⁻', x => x%1===0 && x <= 0, x => Math.min(Math.floor(x)+1, 0), x => Math.min(Math.ceil(x)-1, 0)) Domain.ZM.latexMarkup = "\\mathbb{Z}^{-}" -Domain.ZME = new SpecialDomain('ℤ⁻*', x => x%1==0 && x < 0, +Domain.ZME = new SpecialDomain('ℤ⁻*', x => x%1===0 && x < 0, x => Math.min(Math.floor(x)+1, -1), x => Math.min(Math.ceil(x)-1, -1)) Domain.ZME.latexMarkup = "\\mathbb{Z}^{-*}" Domain.NLog = new SpecialDomain('ℕˡᵒᵍ', - x => x/Math.pow(10, x.toString().length-1) % 1 == 0 && x > 0, + x => x/Math.pow(10, x.toString().length-1) % 1 === 0 && x > 0, function(x) { - var x10pow = Math.pow(10, x.toString().length-1) + let x10pow = Math.pow(10, x.toString().length-1) return Math.max(1, (Math.floor(x/x10pow)+1)*x10pow) }, function(x) { - var x10pow = Math.pow(10, x.toString().length-1) + let x10pow = Math.pow(10, x.toString().length-1) return Math.max(1, (Math.ceil(x/x10pow)-1)*x10pow) }) Domain.NLog.latexMarkup = "\\mathbb{N}^{log}" -var refedDomains = [] +let refedDomains = [] /** - * Parses a domain, that can use parenthesises. + * Parses a domain, that can use parentheses. * e.g (N ∪ [-1;0[) ∩ (Z \ {0;3}) * @param {string} domain - string of the domain to be parsed. * @returns {Domain} Parsed domain. */ -function parseDomain(domain) { +export function parseDomain(domain) { if(!domain.includes(')') && !domain.includes('(')) return parseDomainSimple(domain) - var domStr + let domStr while((domStr = /\(([^)(]+)\)/.exec(domain)) !== null) { - var dom = parseDomainSimple(domStr[1].trim()); + let dom = parseDomainSimple(domStr[1].trim()); domain = domain.replace(domStr[0], 'D' + refedDomains.length) refedDomains.push(dom) } @@ -605,20 +602,20 @@ function parseDomain(domain) { } /** - * Parses a domain, without parenthesises. + * Parses a domain, without parentheses. * e.g N ∪ [-1;0[, Z \ {0;3}, N+*... * @param {string} domain - string of the domain to be parsed. * @returns {Domain} Parsed domain. */ -function parseDomainSimple(domain) { +export function parseDomainSimple(domain) { domain = domain.trim() if(domain.includes("U") || domain.includes("∪")) return UnionDomain.import(domain) if(domain.includes("∩")) return IntersectionDomain.import(domain) if(domain.includes("∖") || domain.includes("\\")) return MinusDomain.import(domain) - if(domain.charAt(0) == "{" && domain.charAt(domain.length -1) == "}") return DomainSet.import(domain) + if(domain.charAt(0) === "{" && domain.charAt(domain.length -1) === "}") return DomainSet.import(domain) if(domain.includes("]") || domain.includes("[")) return Range.import(domain) if(["R", "ℝ", "N", "ℕ", "Z", "ℤ"].some(str => domain.toUpperCase().includes(str))) return Domain.import(domain) - if(domain[0] == 'D') return refedDomains[parseInt(domain.substr(1))] + if(domain[0] === 'D') return refedDomains[parseInt(domain.substr(1))] return new EmptySet() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs similarity index 63% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 4a57746..3a16499 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -16,21 +16,25 @@ * along with this program. If not, see . */ -.pragma library -.import "common.js" as C -.import "latex.js" as Latex -.import "../utils.js" as Utils +import Latex from "latex.mjs" +import * as Utils from "../utils.mjs" /** * Represents any kind of x-based or non variable based expression. */ -class Expression { +export class Expression { constructor(expr) { + if(!Runtime.ExprParser) + throw new Error('Expression parser not initialized.') + if(!Runtime.Objects) + throw new Error('Objects API not initialized.') this.expr = Utils.exponentsToExpression(expr) - this.calc = C.parser.parse(this.expr).simplify() + this.calc = Runtime.ExprParser.parse(this.expr).simplify() this.cached = this.isConstant() - this.cachedValue = this.cached && this.allRequirementsFullfilled() ? this.calc.evaluate(C.currentObjectsByName) : null + this.cachedValue = null + if(this.cached && this.allRequirementsFullfilled()) + this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) this.latexMarkup = Latex.expression(this.calc.tokens) } @@ -40,37 +44,37 @@ class Expression { } requiredObjects() { - return this.calc.variables().filter(objName => objName != "x" && objName != "n") + return this.calc.variables().filter(objName => objName !== "x" && objName !== "n") } allRequirementsFullfilled() { - return this.requiredObjects().every(objName => objName in C.currentObjectsByName) + return this.requiredObjects().every(objName => objName in Runtime.Objects.currentObjectsByName) } undefinedVariables() { - return this.requiredObjects().filter(objName => !(objName in C.currentObjectsByName)) + return this.requiredObjects().filter(objName => !(objName in Runtime.Objects.currentObjectsByName)) } recache() { if(this.cached) - this.cachedValue = this.calc.evaluate(C.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) } execute(x = 1) { if(this.cached) { if(this.cachedValue == null) - this.cachedValue = this.calc.evaluate(C.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) return this.cachedValue } - C.currentVars = Object.assign({'x': x}, C.currentObjectsByName) - return this.calc.evaluate(C.currentVars) + Runtime.ExprParser.currentVars = Object.assign({'x': x}, Runtime.Objects.currentObjectsByName) + return this.calc.evaluate(Runtime.ExprParser.currentVars) } simplify(x) { - var expr = this.calc.substitute('x', x).simplify() - if(expr.evaluate() == 0) return '0' - var str = Utils.makeExpressionReadable(expr.toString()); - if(str != undefined && str.match(/^\d*\.\d+$/)) { + let expr = this.calc.substitute('x', x).simplify() + if(expr.evaluate() === 0) return '0' + let str = Utils.makeExpressionReadable(expr.toString()); + if(str !== undefined && str.match(/^\d*\.\d+$/)) { if(str.split('.')[1].split('0').length > 7) { // Likely rounding error str = parseFloat(str.substring(0, str.length-1)).toString(); @@ -89,11 +93,11 @@ class Expression { toString(forceSign=false) { let str = Utils.makeExpressionReadable(this.calc.toString()) - if(str[0] != '-' && forceSign) str = '+' + str + if(str[0] !== '-' && forceSign) str = '+' + str return str } } -function executeExpression(expr){ +export function executeExpression(expr){ return (new Expression(expr.toString())).execute() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js deleted file mode 100644 index 50883b2..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.js +++ /dev/null @@ -1,282 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -.pragma library - -.import "../expr-eval.js" as ExprEval - - -/** - * true if latex has been enabled by the user, false otherwise. - */ -var enabled = false -/** - * LaTeX python backend QObject. - */ -var Renderer = null -/** - * Default window color used to render LaTeX formulas. - */ -var defaultColor = "black" - -/** - * Puts element within parenthesis. - * - * @param {string} elem - element to put within parenthesis. - * @returns {string} - */ -function par(elem) { - return '(' + elem + ')' -} - -/** - * Checks if the element contains at least one of the elements of - * the string array contents, but not at the first position of the string, - * and returns the parenthesis version if so. - * - * @param {string} elem - element to put within parenthesis. - * @param {Array} contents - Array of elements to put within parenthesis. - * @returns {string} - */ -function parif(elem, contents) { - elem = elem.toString() - if(elem[0] != "(" && elem[elem.length-1] != ")" && contents.some(x => elem.indexOf(x) > 0)) - return par(elem) - if(elem[0] == "(" && elem[elem.length-1] == ")") - return elem.substr(1, elem.length-2) - return elem -} - - -/** - * Creates a latex expression for a function. - * - * @param {string} f - Function to convert - * @param {Array} args - Arguments of the function - * @returns {string} - */ -function functionToLatex(f, args) { - switch(f) { - case "derivative": - if(args.length == 3) - return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; - else - return '\\frac{d' + args[0] + '}{dx}(x)'; - break; - case "integral": - if(args.length == 4) - return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); - else - return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2] + '(t) dt'; - break; - case "sqrt": - return '\\sqrt\\left(' + args.join(', ') + '\\right)'; - break; - case "abs": - return '\\left|' + args.join(', ') + '\\right|'; - break; - case "floor": - return '\\left\\lfloor' + args.join(', ') + '\\right\\rfloor'; - break; - case "ceil": - return '\\left\\lceil' + args.join(', ') + '\\right\\rceil'; - break; - default: - return '\\mathrm{' + f + '}\\left(' + args.join(', ') + '\\right)'; - break; - } -} - - -/** - * Creates a latex variable from a variable. - * - * @param {string} vari - variable text to convert - * @param {bool} wrapIn$ - checks whether the escaped chars should be escaped - * @returns {string} - */ -function variable(vari, wrapIn$ = false) { - let unicodechars = ["α","β","γ","δ","ε","ζ","η", - "π","θ","κ","λ","μ","ξ","ρ", - "ς","σ","τ","φ","χ","ψ","ω", - "Γ","Δ","Θ","Λ","Ξ","Π","Σ", - "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", - "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", - "ₜ","¹","²","³","⁴","⁵","⁶", - "⁷","⁸","⁹","⁰","₁","₂","₃", - "₄","₅","₆","₇","₈","₉","₀", - "pi", "∞"] - let equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta","\\eta", - "\\pi","\\theta","\\kappa","\\lambda","\\mu","\\xi","\\rho", - "\\sigma","\\sigma","\\tau","\\phi","\\chi","\\psi","\\omega", - "\\Gamma","\\Delta","\\Theta","\\Lambda","\\Xi","\\Pi","\\Sigma", - "\\Phy","\\Psi","\\Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", - "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", - "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", - "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", - "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", - "\\pi", "\\infty"] - if(wrapIn$) - for(let i = 0; i < unicodechars.length; i++) { - if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], 'g'), '$'+equivalchars[i]+'$') - } - else - for(let i = 0; i < unicodechars.length; i++) { - if(vari.includes(unicodechars[i])) - vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i]) - } - return vari; -} - -/** - * Converts expr-eval tokens to a latex string. - * - * @param {Array} tokens - expr-eval tokens list - * @returns {string} - */ -function expression(tokens) { - var nstack = []; - var n1, n2, n3; - var f, args, argCount; - for (var i = 0; i < tokens.length; i++) { - var item = tokens[i]; - var type = item.type; - - switch(type) { - case ExprEval.INUMBER: - if(item.value == Infinity) { - nstack.push("\\infty") - } else if(typeof item.value === 'number' && item.value < 0) { - nstack.push(par(item.value)); - } else if(Array.isArray(item.value)) { - nstack.push('[' + item.value.map(ExprEval.escapeValue).join(', ') + ']'); - } else { - nstack.push(ExprEval.escapeValue(item.value)); - } - break; - case ExprEval.IOP2: - n2 = nstack.pop(); - n1 = nstack.pop(); - f = item.value; - switch(f) { - case '-': - case '+': - nstack.push(n1 + f + n2); - break; - case '||': - case 'or': - case '&&': - case 'and': - case '==': - case '!=': - nstack.push(par(n1) + f + par(n2)); - break; - case '*': - if(n2 == "\\pi" || n2 == "e" || n2 == "x" || n2 == "n") - nstack.push(parif(n1,['+','-']) + n2) - else - nstack.push(parif(n1,['+','-']) + " \\times " + parif(n2,['+','-'])); - break; - case '/': - nstack.push("\\frac{" + n1 + "}{" + n2 + "}"); - break; - case '^': - nstack.push(parif(n1,['+','-','*','/','!']) + "^{" + n2 + "}"); - break; - case '%': - nstack.push(parif(n1,['+','-','*','/','!','^']) + " \\mathrm{mod} " + parif(n2,['+','-','*','/','!','^'])); - break; - case '[': - nstack.push(n1 + '[' + n2 + ']'); - break; - default: - throw new EvalError("Unknown operator " + ope + "."); - } - break; - case ExprEval.IOP3: // Thirdiary operator - n3 = nstack.pop(); - n2 = nstack.pop(); - n1 = nstack.pop(); - f = item.value; - if (f === '?') { - nstack.push('(' + n1 + ' ? ' + n2 + ' : ' + n3 + ')'); - } else { - throw new EvalError('Unknown operator ' + ope + '.'); - } - break; - case ExprEval.IVAR: - case ExprEval.IVARNAME: - nstack.push(variable(item.value.toString())); - break; - case ExprEval.IOP1: // Unary operator - n1 = nstack.pop(); - f = item.value; - switch(f) { - case '-': - case '+': - nstack.push(par(f + n1)); - break; - case '!': - nstack.push(parif(n1,['+','-','*','/','^']) + '!'); - break; - default: - nstack.push(f + parif(n1,['+','-','*','/','^'])); - break; - } - break; - case ExprEval.IFUNCALL: - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - f = nstack.pop(); - // Handling various functions - nstack.push(functionToLatex(f, args)) - break; - case ExprEval.IFUNDEF: - nstack.push(par(n1 + '(' + args.join(', ') + ') = ' + n2)); - break; - case ExprEval.IMEMBER: - n1 = nstack.pop(); - nstack.push(n1 + '.' + item.value); - break; - case ExprEval.IARRAY: - argCount = item.value; - args = []; - while (argCount-- > 0) { - args.unshift(nstack.pop()); - } - nstack.push('[' + args.join(', ') + ']'); - break; - case ExprEval.IEXPR: - nstack.push('(' + expression(item.value) + ')'); - break; - case ExprEval.IENDSTATEMENT: - break; - default: - throw new EvalError('invalid Expression'); - break; - } - } - if (nstack.length > 1) { - nstack = [ nstack.join(';') ] - } - return String(nstack[0]); -} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs new file mode 100644 index 0000000..c7975e7 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs @@ -0,0 +1,288 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { RuntimeAPI } from '../runtime.mjs' + +const unicodechars = ["α","β","γ","δ","ε","ζ","η", + "π","θ","κ","λ","μ","ξ","ρ", + "ς","σ","τ","φ","χ","ψ","ω", + "Γ","Δ","Θ","Λ","Ξ","Π","Σ", + "Φ","Ψ","Ω","ₐ","ₑ","ₒ","ₓ", + "ₕ","ₖ","ₗ","ₘ","ₙ","ₚ","ₛ", + "ₜ","¹","²","³","⁴","⁵","⁶", + "⁷","⁸","⁹","⁰","₁","₂","₃", + "₄","₅","₆","₇","₈","₉","₀", + "pi", "∞"] +const equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta","\\eta", + "\\pi","\\theta","\\kappa","\\lambda","\\mu","\\xi","\\rho", + "\\sigma","\\sigma","\\tau","\\phi","\\chi","\\psi","\\omega", + "\\Gamma","\\Delta","\\Theta","\\Lambda","\\Xi","\\Pi","\\Sigma", + "\\Phy","\\Psi","\\Omega","{}_{a}","{}_{e}","{}_{o}","{}_{x}", + "{}_{h}","{}_{k}","{}_{l}","{}_{m}","{}_{n}","{}_{p}","{}_{s}", + "{}_{t}","{}^{1}","{}^{2}","{}^{3}","{}^{4}","{}^{5}","{}^{6}", + "{}^{7}","{}^{8}","{}^{9}","{}^{0}","{}_{1}","{}_{2}","{}_{3}", + "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", + "\\pi", "\\infty"] + +console.log(Runtime.ExprParser) + +class LatexAPI extends RuntimeAPI { + constructor() { + super('Latex', [ + /** @type {ExprParserAPI} */ + Runtime.ExprParser + ]) + /** + * true if latex has been enabled by the user, false otherwise. + */ + this.enabled = false + /** + * LaTeX python backend QObject. + */ + this.Renderer = null + } + + /** + * Puts element within parenthesis. + * + * @param {string} elem - element to put within parenthesis. + * @returns {string} + */ + par(elem) { + return '(' + elem + ')' + } + + /** + * Checks if the element contains at least one of the elements of + * the string array contents, but not at the first position of the string, + * and returns the parenthesis version if so. + * + * @param {string} elem - element to put within parenthesis. + * @param {Array} contents - Array of elements to put within parenthesis. + * @returns {string} + */ + parif(elem, contents) { + elem = elem.toString() + if(elem[0] !== "(" && elem[elem.length-1] !== ")" && contents.some(x => elem.indexOf(x) > 0)) + return this.par(elem) + if(elem[0] === "(" && elem[elem.length-1] === ")") + return elem.substr(1, elem.length-2) + return elem + } + + /** + * Creates a latex expression for a function. + * + * @param {string} f - Function to convert + * @param {(number,string)[]} args - Arguments of the function + * @returns {string} + */ + functionToLatex(f, args) { + switch(f) { + case "derivative": + if(args.length === 3) + return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}'; + else + return '\\frac{d' + args[0] + '}{dx}(x)'; + break; + case "integral": + if(args.length === 4) + return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2); + else + return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2] + '(t) dt'; + break; + case "sqrt": + return '\\sqrt\\left(' + args.join(', ') + '\\right)'; + break; + case "abs": + return '\\left|' + args.join(', ') + '\\right|'; + break; + case "floor": + return '\\left\\lfloor' + args.join(', ') + '\\right\\rfloor'; + break; + case "ceil": + return '\\left\\lceil' + args.join(', ') + '\\right\\rceil'; + break; + default: + return '\\mathrm{' + f + '}\\left(' + args.join(', ') + '\\right)'; + break; + } + } + + /** + * Creates a latex variable from a variable. + * + * @param {string} vari - variable text to convert + * @param {boolean} wrapIn$ - checks whether the escaped chars should be escaped + * @returns {string} + */ + variable(vari, wrapIn$ = false) { + if(wrapIn$) + for(let i = 0; i < unicodechars.length; i++) { + if(vari.includes(unicodechars[i])) + vari = vari.replace(new RegExp(unicodechars[i], 'g'), '$'+equivalchars[i]+'$') + } + else + for(let i = 0; i < unicodechars.length; i++) { + if(vari.includes(unicodechars[i])) + vari = vari.replace(new RegExp(unicodechars[i], 'g'), equivalchars[i]) + } + return vari; + } + + /** + * Converts expr-eval tokens to a latex string. + * + * @param {Array} tokens - expr-eval tokens list + * @returns {string} + */ + expression(tokens) { + let nstack = [] + let n1, n2, n3 + let f, args, argCount + for (let i = 0; i < tokens.length; i++) { + let item = tokens[i] + let type = item.type + + switch(type) { + case Runtime.ExprParser.Internals.INUMBER: + if(item.value === Infinity) { + nstack.push("\\infty") + } else if(typeof item.value === 'number' && item.value < 0) { + nstack.push(this.par(item.value)); + } else if(Array.isArray(item.value)) { + nstack.push('[' + item.value.map(Runtime.ExprParser.Internals.escapeValue).join(', ') + ']'); + } else { + nstack.push(Runtime.ExprParser.Internals.escapeValue(item.value)); + } + break; + case Runtime.ExprParser.Internals.IOP2: + n2 = nstack.pop(); + n1 = nstack.pop(); + f = item.value; + switch(f) { + case '-': + case '+': + nstack.push(n1 + f + n2); + break; + case '||': + case 'or': + case '&&': + case 'and': + case '==': + case '!=': + nstack.push(this.par(n1) + f + this.par(n2)); + break; + case '*': + if(n2 == "\\pi" || n2 == "e" || n2 == "x" || n2 == "n") + nstack.push(this.parif(n1,['+','-']) + n2) + else + nstack.push(this.parif(n1,['+','-']) + " \\times " + this.parif(n2,['+','-'])); + break; + case '/': + nstack.push("\\frac{" + n1 + "}{" + n2 + "}"); + break; + case '^': + nstack.push(this.parif(n1,['+','-','*','/','!']) + "^{" + n2 + "}"); + break; + case '%': + nstack.push(this.parif(n1,['+','-','*','/','!','^']) + " \\mathrm{mod} " + parif(n2,['+','-','*','/','!','^'])); + break; + case '[': + nstack.push(n1 + '[' + n2 + ']'); + break; + default: + throw new EvalError("Unknown operator " + ope + "."); + } + break; + case Runtime.ExprParser.Internals.IOP3: // Thirdiary operator + n3 = nstack.pop(); + n2 = nstack.pop(); + n1 = nstack.pop(); + f = item.value; + if (f === '?') { + nstack.push('(' + n1 + ' ? ' + n2 + ' : ' + n3 + ')'); + } else { + throw new EvalError('Unknown operator ' + ope + '.'); + } + break; + case Runtime.ExprParser.Internals.IVAR: + case Runtime.ExprParser.Internals.IVARNAME: + nstack.push(this.variable(item.value.toString())); + break; + case Runtime.ExprParser.Internals.IOP1: // Unary operator + n1 = nstack.pop(); + f = item.value; + switch(f) { + case '-': + case '+': + nstack.push(this.par(f + n1)); + break; + case '!': + nstack.push(this.parif(n1,['+','-','*','/','^']) + '!'); + break; + default: + nstack.push(f + this.parif(n1,['+','-','*','/','^'])); + break; + } + break; + case Runtime.ExprParser.Internals.IFUNCALL: + argCount = item.value; + args = []; + while (argCount-- > 0) { + args.unshift(nstack.pop()); + } + f = nstack.pop(); + // Handling various functions + nstack.push(this.functionToLatex(f, args)) + break; + case Runtime.ExprParser.Internals.IFUNDEF: + nstack.push(this.par(n1 + '(' + args.join(', ') + ') = ' + n2)); + break; + case Runtime.ExprParser.Internals.IMEMBER: + n1 = nstack.pop(); + nstack.push(n1 + '.' + item.value); + break; + case Runtime.ExprParser.Internals.IARRAY: + argCount = item.value; + args = []; + while (argCount-- > 0) { + args.unshift(nstack.pop()); + } + nstack.push('[' + args.join(', ') + ']'); + break; + case Runtime.ExprParser.Internals.IEXPR: + nstack.push('(' + this.expression(item.value) + ')'); + break; + case Runtime.ExprParser.Internals.IENDSTATEMENT: + break; + default: + throw new EvalError('invalid Expression'); + } + } + if (nstack.length > 1) { + nstack = [ nstack.join(';') ] + } + return String(nstack[0]); + } +} + +/** @type {LatexAPI} */ +Runtime.Latex = Runtime.Latex || new LatexAPI() + +export default Runtime.Latex diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs similarity index 66% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index cd0960a..2dafdcd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -16,18 +16,14 @@ * along with this program. If not, see . */ -.pragma library - -.import "common.js" as C -.import "expression.js" as Expr -.import "../utils.js" as Utils -.import "../math/latex.js" as Latex - +import * as Expr from "expression.mjs" +import * as Utils from "../utils.mjs" +import Latex from "../math/latex.mjs" /** * Represents mathematical object for sequences. */ -class Sequence extends Expr.Expression { +export class Sequence extends Expr.Expression { constructor(name, baseValues = {}, valuePlus = 1, expr = "") { // u[n+valuePlus] = expr super(expr) @@ -35,9 +31,9 @@ class Sequence extends Expr.Expression { this.baseValues = baseValues this.calcValues = Object.assign({}, baseValues) this.latexValues = Object.assign({}, baseValues) - for(var n in this.calcValues) + for(let n in this.calcValues) if(['string', 'number'].includes(typeof this.calcValues[n])) { - let parsed = C.parser.parse(this.calcValues[n].toString()).simplify() + let parsed = Runtime.ExprParser.parse(this.calcValues[n].toString()).simplify() this.latexValues[n] = Latex.expression(parsed.tokens) this.calcValues[n] = parsed.evaluate() } @@ -45,7 +41,7 @@ class Sequence extends Expr.Expression { } isConstant() { - return this.expr.indexOf("n") == -1 + return this.expr.indexOf("n") === -1 } execute(n = 1) { @@ -63,25 +59,25 @@ class Sequence extends Expr.Expression { } cache(n = 1) { - var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) - var expr = C.parser.parse(str).simplify() - // Chache values required for this one. + let str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) + let expr = Runtime.ExprParser.parse(str).simplify() + // Cache values required for this one. if(!this.calcValues[n-this.valuePlus] && n-this.valuePlus > 0) this.cache(n-this.valuePlus) // Setting current variables - C.currentVars = Object.assign( + Runtime.ExprParser.currentVars = Object.assign( {'n': n-this.valuePlus}, // Just in case, add n (for custom functions) - C.currentObjectsByName, + Runtime.Objects.currentObjectsByName, {[this.name]: this.calcValues} ) - this.calcValues[n] = expr.evaluate(C.currentVars) + this.calcValues[n] = expr.evaluate(Runtime.ExprParser.currentVars) } toString(forceSign=false) { - var str = Utils.makeExpressionReadable(this.calc.toString()) - if(str[0] != '-' && forceSign) str = '+' + str - var subtxt = this.valuePlus == 0 ? 'ₙ' : Utils.textsub('n+' + this.valuePlus) - var ret = `${this.name}${subtxt} = ${str}${this.baseValues.length == 0 ? '' : "\n"}` + let str = Utils.makeExpressionReadable(this.calc.toString()) + if(str[0] !== '-' && forceSign) str = '+' + str + let subtxt = this.valuePlus === 0 ? 'ₙ' : Utils.textsub('n+' + this.valuePlus) + let ret = `${this.name}${subtxt} = ${str}${this.baseValues.length === 0 ? '' : "\n"}` ret += Object.keys(this.baseValues).map( n => `${this.name}${Utils.textsub(n)} = ${this.baseValues[n]}` ).join('; ') @@ -89,10 +85,10 @@ class Sequence extends Expr.Expression { } toLatexString(forceSign=false) { - var str = this.latexMarkup - if(str[0] != '-' && forceSign) str = '+' + str - var subtxt = '_{n' + (this.valuePlus == 0 ? '' : '+' + this.valuePlus) + '}' - var ret = `\\begin{array}{l}${Latex.variable(this.name)}${subtxt} = ${str}${this.latexValues.length == 0 ? '' : "\n"}\\\\` + let str = this.latexMarkup + if(str[0] !== '-' && forceSign) str = '+' + str + let subtxt = '_{n' + (this.valuePlus === 0 ? '' : '+' + this.valuePlus) + '}' + let ret = `\\begin{array}{l}${Latex.variable(this.name)}${subtxt} = ${str}${this.latexValues.length === 0 ? '' : "\n"}\\\\` ret += Object.keys(this.latexValues).map( n => `${this.name}_{${n}} = ${this.latexValues[n]}` ).join('; ') + "\\end{array}" diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs similarity index 54% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs index 9ecb377..88f9c1e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/mathlib.mjs @@ -16,26 +16,25 @@ * along with this program. If not, see . */ -.pragma library -.import "math/expression.js" as Expr -.import "math/sequence.js" as Seq +import * as Expr from "math/expression.mjs" +import * as Seq from "math/sequence.mjs" +import * as Dom from "math/domain.mjs" -.import "math/domain.js" as Dom -var Expression = Expr.Expression -var executeExpression = Expr.executeExpression -var Sequence = Seq.Sequence +export const Expression = Expr.Expression +export const executeExpression = Expr.executeExpression +export const Sequence = Seq.Sequence // Domains -var Domain = Dom.Domain -var EmptySet = Dom.EmptySet -var Range = Dom.Range -var SpecialDomain = Dom.SpecialDomain -var DomainSet = Dom.DomainSet -var UnionDomain = Dom.UnionDomain -var IntersectionDomain = Dom.IntersectionDomain -var MinusDomain = Dom.MinusDomain +export const Domain = Dom.Domain +export const EmptySet = Dom.EmptySet +export const Range = Dom.Range +export const SpecialDomain = Dom.SpecialDomain +export const DomainSet = Dom.DomainSet +export const UnionDomain = Dom.UnionDomain +export const IntersectionDomain = Dom.IntersectionDomain +export const MinusDomain = Dom.MinusDomain -var parseDomain = Dom.parseDomain -var parseDomainSimple = Dom.parseDomainSimple +export const parseDomain = Dom.parseDomain +export const parseDomainSimple = Dom.parseDomainSimple diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js new file mode 100644 index 0000000..773f1c3 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js @@ -0,0 +1,7 @@ + +// Loading modules in order +.import "objects.mjs" as Objects +.import "lib/expr-eval/integration.js" as ExprParser +.import "objs/autoload.mjs" as Autoload +.import "math/latex.mjs" as Latex +.import "history/common.mjs" as HistoryCommon diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js deleted file mode 100644 index 90dd468..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -.pragma library - -.import "utils.js" as Utils -.import "math/common.js" as MathCommons -.import "parameters.js" as P - -var types = {} - -var currentObjects = {} -var currentObjectsByName = {} -MathCommons.currentObjectsByName = currentObjectsByName // Required for using objects in variables. - -function renameObject(oldName, newName) { - /** - * Renames an object from its old name to the new one. - * @param {string} oldName - Current name of the object. - * @param {string} newName - Name to rename the object to. - */ - let obj = currentObjectsByName[oldName] - delete currentObjectsByName[oldName] - currentObjectsByName[newName] = obj - obj.name = newName -} - -function deleteObject(objName) { - /** - * Deletes an object by its given name. - * @param {string} objName - Current name of the object. - */ - let obj = currentObjectsByName[objName] - currentObjects[obj.type].splice(currentObjects[obj.type].indexOf(obj),1) - obj.delete() - delete currentObjectsByName[objName] -} - -function getObjectsName(objType) { - /** - * Gets a list of all names of a certain object type. - * @param {string} objType - Type of the object to query. Can be ExecutableObject for all ExecutableObjects. - * @return {array} List of names of the objects. - */ - if(objType == "ExecutableObject") { - // NOTE: QMLJS does not support flatMap. - // return getExecutableTypes().flatMap(elemType => currentObjects[elemType].map(obj => obj.name)) - let types = getExecutableTypes() - let elementNames = [''] - for(let elemType of types) - elementNames = elementNames.concat(currentObjects[elemType].map(obj => obj.name)) - return elementNames - } - if(currentObjects[objType] == undefined) return [] - return currentObjects[objType].map(obj => obj.name) -} - -function getExecutableTypes() { - /** - * Returns a list of all object types which are executable objects. - * @return {array} List of all object types which are executable objects. - */ - return Object.keys(currentObjects).filter(objType => types[objType].executable()) -} - -function createNewRegisteredObject(objType, args=[]) { - /** - * Creates and register an object in the database. - * @param {string} objType - Type of the object to create. - * @param {string} args - List of arguments for the objects (can be empty). - * @return {[objType]} Newly created object. - */ - if(Object.keys(types).indexOf(objType) == -1) return null // Object type does not exist. - var newobj = new types[objType](...args) - if(Object.keys(currentObjects).indexOf(objType) == -1) { - currentObjects[objType] = [] - } - currentObjects[objType].push(newobj) - currentObjectsByName[newobj.name] = newobj - return newobj -} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs new file mode 100644 index 0000000..b7a2dae --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs @@ -0,0 +1,112 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { RuntimeAPI } from './runtime.mjs' + +class ObjectsAPI extends RuntimeAPI { + + constructor() { + super('Objects') + + this.types = {} + /** + * List of objects for each type of object. + * @type {Object.} + */ + this.currentObjects = {} + /** + * List of objects matched by their name. + * @type {Object.} + */ + this.currentObjectsByName = {} + } + + /** + * Renames an object from its old name to the new one. + * @param {string} oldName - Current name of the object. + * @param {string} newName - Name to rename the object to. + */ + renameObject(oldName, newName) { + let obj = this.currentObjectsByName[oldName] + delete this.currentObjectsByName[oldName] + this.currentObjectsByName[newName] = obj + obj.name = newName + } + + /** + * Deletes an object by its given name. + * @param {string} objName - Current name of the object. + */ + deleteObject(objName) { + let obj = this.currentObjectsByName[objName] + if(obj !== undefined) { + this.currentObjects[obj.type].splice(this.currentObjects[obj.type].indexOf(obj),1) + obj.delete() + delete this.currentObjectsByName[objName] + } + } + + /** + * Gets a list of all names of a certain object type. + * @param {string} objType - Type of the object to query. Can be ExecutableObject for all ExecutableObjects. + * @returns {string[]} List of names of the objects. + */ + getObjectsName(objType) { + if(objType === "ExecutableObject") { + // NOTE: QMLJS does not support flatMap. + // return getExecutableTypes().flatMap(elemType => currentObjects[elemType].map(obj => obj.name)) + let types = this.getExecutableTypes() + let elementNames = [''] + for(let elemType of types) + elementNames = elementNames.concat(this.currentObjects[elemType].map(obj => obj.name)) + return elementNames + } + if(this.currentObjects[objType] === undefined) return [] + return this.currentObjects[objType].map(obj => obj.name) + } + + /** + * Returns a list of all object types which are executable objects. + * @return {string[]} List of all object types which are executable objects. + */ + getExecutableTypes() { + return Object.keys(this.currentObjects).filter(objType => this.types[objType].executable()) + } + + /** + * Creates and register an object in the database. + * @param {string} objType - Type of the object to create. + * @param {string[]} args - List of arguments for the objects (can be empty). + * @return {DrawableObject} Newly created object. + */ + createNewRegisteredObject(objType, args= []) { + if(Object.keys(this.types).indexOf(objType) === -1) return null // Object type does not exist. + let newobj = new this.types[objType](...args) + if(Object.keys(this.currentObjects).indexOf(objType) === -1) { + this.currentObjects[objType] = [] + } + this.currentObjects[objType].push(newobj) + this.currentObjectsByName[newobj.name] = newobj + return newobj + } +} + +/** @type {ObjectsAPI} */ +Runtime.Objects = Runtime.Objects || new ObjectsAPI() + +export default Runtime.Objects diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs new file mode 100644 index 0000000..c3e8f63 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -0,0 +1,42 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { API as ObjectsCommonAPI } from "common.mjs" +import Point from "point.mjs" +import Text from "text.mjs" +import Function from "function.mjs" +import GainBode from "gainbode.mjs" +import PhaseBode from "phasebode.mjs" +import SommeGainsBode from "sommegainsbode.mjs" +import SommePhasesBode from "sommephasesbode.mjs" +import XCursor from "xcursor.mjs" +import Sequence from "sequence.mjs" +import RepartitionFunction from "repartition.mjs" + +if(Object.keys(Runtime.Objects.types).length === 0) { + ObjectsCommonAPI.registerObject(Point) + ObjectsCommonAPI.registerObject(Text) + ObjectsCommonAPI.registerObject(Function) + ObjectsCommonAPI.registerObject(GainBode) + ObjectsCommonAPI.registerObject(PhaseBode) + ObjectsCommonAPI.registerObject(SommeGainsBode) + ObjectsCommonAPI.registerObject(SommePhasesBode) + ObjectsCommonAPI.registerObject(XCursor) + ObjectsCommonAPI.registerObject(Sequence) + ObjectsCommonAPI.registerObject(RepartitionFunction) +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs similarity index 77% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index bc31bac..7821037 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -16,42 +16,71 @@ * along with this program. If not, see . */ -.pragma library - -.import "../utils.js" as Utils -.import "../objects.js" as Objects -.import "../math/latex.js" as Latex -.import "../parameters.js" as P -.import "../math/common.js" as C +import { getRandomColor, textsub } from "../utils.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" +import {RuntimeAPI} from "../runtime.mjs" // This file contains the default data to be imported from all other objects -/** - * Creates a new name for an object, based on the \c allowedLetters. - * If variables with each of the allowedLetters is created, a subscript - * number is added to the name. - * @param {string} prefix - Prefix to the name. - * @return {string} New unused name for a new object. - */ -function getNewName(allowedLetters, prefix='') { - // Allows to get a new name, based on the allowed letters, - // as well as adding a sub number when needs be. - var newid = 0 - var ret - do { - var letter = allowedLetters[newid % allowedLetters.length] - var num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) - ret = prefix + letter + (num > 0 ? Utils.textsub(num-1) : '') - newid += 1 - } while(ret in Objects.currentObjectsByName) - return ret +class ObjectsCommonAPI extends RuntimeAPI { + + constructor() { + super('ObjectsCommon', [ + Runtime.Objects, + Runtime.ExprParser, + Runtime.Latex + ]) + } + + /** + * Creates a new name for an object, based on the \c allowedLetters. + * If variables with each of the allowedLetters is created, a subscript + * number is added to the name. + * @param {string} allowedLetters + * @param {string} prefix - Prefix to the name. + * @return {string} New unused name for a new object. + */ + getNewName(allowedLetters, prefix='') { + // Allows to get a new name, based on the allowed letters, + // as well as adding a sub number when needs be. + let newid = 0 + let ret + do { + let letter = allowedLetters[newid % allowedLetters.length] + let num = Math.floor((newid - (newid % allowedLetters.length)) / allowedLetters.length) + ret = prefix + letter + (num > 0 ? textsub(num-1) : '') + newid += 1 + } while(ret in Objects.currentObjectsByName) + return ret + } + + /** + * Registers the object \c obj in the object list. + * @param {DrawableObject} obj - Object to be registered. + */ + registerObject(obj) { + // Registers an object to be used in LogarithmPlotter. + // This function is called from autoload.mjs + if(obj.prototype instanceof DrawableObject) { + if(!Objects.types[obj.type()]) + Objects.types[obj.type()] = obj + } else { + console.error("Could not register object " + (obj.type()) + ", as it isn't a DrawableObject.") + } + } } +/** @type {ObjectsCommonAPI} */ +Runtime.ObjectsCommon = Runtime.ObjectsCommon || new ObjectsCommonAPI() + +export const API = Runtime.ObjectsCommon + /** * Class to extend for every type of object that * can be drawn on the canvas. */ -class DrawableObject { +export class DrawableObject { /** * Base name of the object. Needs to be constant over time. * @return {string} Type of the object. @@ -73,7 +102,7 @@ class DrawableObject { /** * True if this object can be created by the user, false if it can only * be instantiated by other objects - * @return {bool} + * @return {boolean} */ static createable() {return true} @@ -89,30 +118,30 @@ class DrawableObject { * If the property is to be translated, the key should be passed * through the QT_TRANSLATE_NOOP macro in that form: * [QT_TRANSLATE_NOOP('prop','key')] - * Enums that are translated should be indexed in parameters.js and + * Enums that are translated should be indexed in parameters.mjs and * then be linked directly here. * - * @return {Dictionary} + * @return {Object.} */ static properties() {return {}} /** * True if this object can be executed, so that an y value might be computed * for an x value. Only ExecutableObjects have that property set to true. - * @return {bool} + * @return {boolean} */ static executable() {return false} /** * Base constructor for the object. * @param {string} name - Name of the object - * @param {bool} visible - true if the object is visible, false otherwise. - * @param {color} color - Color of the object (can be string or QColor) + * @param {boolean} visible - true if the object is visible, false otherwise. + * @param {color|string} color - Color of the object (can be string or QColor) * @param {Enum} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. * @constructor() */ constructor(name, visible = true, color = null, labelContent = 'name + value') { - if(color == null) color = Utils.getRandomColor() + if(color == null) color = getRandomColor() this.type = this.constructor.type() this.name = name this.visible = visible @@ -145,7 +174,7 @@ class DrawableObject { * Latex markuped version of the readable string. * Every non latin character should be passed as latex symbols and formulas * should be in latex form. - * See ../latex.js for helper methods. + * See ../latex.mjs for helper methods. * @return {string} */ getLatexString() { @@ -172,7 +201,7 @@ class DrawableObject { * Latex markup string content of the label depending on the value of the \c latexContent. * Every non latin character should be passed as latex symbols and formulas * should be in latex form. - * See ../latex.js for helper methods. + * See ../latex.mjs for helper methods. * @return {string} */ getLatexLabel() { @@ -204,25 +233,26 @@ class DrawableObject { update() { // Refreshing dependencies. for(let obj of this.requires) - obj.requiredBy = obj.requiredBy.filter(dep => dep != this) + obj.requiredBy = obj.requiredBy.filter(dep => dep !== this) // Checking objects this one depends on this.requires = [] + let currentObjectsByName = Objects.currentObjectsByName let properties = this.constructor.properties() for(let property in properties) if(typeof properties[property] == 'object' && 'type' in properties[property]) - if(properties[property].type == 'Expression' && this[property] != null) { + if(properties[property].type === 'Expression' && this[property] != null) { // Expressions with dependencies for(let objName of this[property].requiredObjects()) { - if(objName in C.currentObjectsByName && !this.requires.includes(C.currentObjectsByName[objName])) { - this.requires.push(C.currentObjectsByName[objName]) - C.currentObjectsByName[objName].requiredBy.push(this) + if(objName in currentObjectsByName && !this.requires.includes(currentObjectsByName[objName])) { + this.requires.push(currentObjectsByName[objName]) + currentObjectsByName[objName].requiredBy.push(this) } } if(this[property].cached && this[property].requiredObjects().length > 0) // Recalculate this[property].recache() - } else if(properties[property].type == 'ObjectType' && this[property] != null) { + } else if(properties[property].type === 'ObjectType' && this[property] != null) { // Object dependency this.requires.push(this[property]) this[property].requiredBy.push(this) @@ -239,12 +269,16 @@ class DrawableObject { for(let toRemove of this.requiredBy) { // Normally, there should be none here, but better leave nothing just in case. Objects.deleteObject(toRemove.name) } + console.log(this.requires) + for(let toRemoveFrom of this.requires) { + toRemoveFrom.requiredBy = toRemoveFrom.requiredBy.filter(o => o !== this) + } } /** * Abstract method. Draw the object onto the \c canvas with the 2D context \c ctx. * @param {Canvas} canvas - * @param {Context2D} ctx + * @param {CanvasRenderingContext2D} ctx */ draw(canvas, ctx) {} @@ -256,7 +290,7 @@ class DrawableObject { * * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} offset - Margin between the position and the object to be drawn - * @param {Dictionary} size - Size of the label item, containing two properties, "width" and "height" + * @param {Object.} size - Size of the label item, containing two properties, "width" and "height" * @param {number} posX - Component of the marked position on the x-axis * @param {number} posY - Component of the marked position on the y-axis * @param {function} drawFunction - Function with two arguments (x, y) that will be called to draw the label @@ -310,17 +344,17 @@ class DrawableObject { * \c drawFunctionText (x,y,text) depending on whether to use latex. * * @param {Canvas} canvas - * @param {Context2D} ctx + * @param {CanvasRenderingContext2D} ctx * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} posX - Component of the marked position on the x-axis * @param {number} posY - Component of the marked position on the y-axis - * @param {bool} forceText - Force the rendering of the label as text + * @param {boolean} forceText - Force the rendering of the label as text * @param {function|null} getLatexFunction - Function (no argument) to get the latex markup to be displayed * @param {function|null} getTextFunction - Function (no argument) to get the text to be displayed * @param {function|null} drawFunctionLatex - Function (x,y,imageData) to display the latex image * @param {function|null} drawFunctionText - Function (x,y,text,textSize) to display the text */ - drawLabel(canvas, ctx, labelPosition, posX, posY, forceText = false, + drawLabel(canvas, ctx, labelPosition, posX, posY,forceText = false, getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) { // Default functions if(getLatexFunction == null) @@ -333,7 +367,7 @@ class DrawableObject { drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, y+textSize.height) // Positioned from left bottom // Drawing the label let offset - if(!forceText && Latex.enabled) { // TODO: Check for user setting with Latex. + if(!forceText && Latex.enabled) { // With latex let drawLblCb = function(canvas, ctx, ltxImg) { this.drawPositionDivergence(labelPosition, 8+ctx.lineWidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) @@ -355,6 +389,7 @@ class DrawableObject { } } + /** * Class to be extended for every object on which * an y for a x can be computed with the execute function. @@ -362,7 +397,7 @@ class DrawableObject { * return null. However, theses same x values will * return false when passed to canExecute. */ -class ExecutableObject extends DrawableObject { +export class ExecutableObject extends DrawableObject { /** * Returns the corresponding y value for an x value. * If the object isn't defined on the given x, then @@ -376,38 +411,25 @@ class ExecutableObject extends DrawableObject { * Returns false if the object isn't defined on the given x, true otherwise. * * @param {number} x - * @returns {bool} + * @returns {boolean} */ canExecute(x = 1) {return true} /** * Returns the simplified expression string for a given x. * * @param {number} x - * @returns {bool} + * @returns {string} */ simplify(x = 1) {return '0'} - /** * True if this object can be executed, so that an y value might be computed * for an x value. Only ExecutableObjects have that property set to true. - * @return {bool} + * @return {boolean} */ static executable() {return true} } -/** - * Registers the object \c obj in the object list. - * @param {DrawableObject} obj - Object to be registered. - */ -function registerObject(obj) { - // Registers an object to be used in LogarithmPlotter. - // This function is called from autoload.js - if(obj.prototype instanceof DrawableObject) { - Objects.types[obj.type()] = obj - } else { - console.error("Could not register object " + (obj.type()) + ", as it isn't a DrawableObject.") - } -} + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs similarity index 90% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index aa43a08..1a52dba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -16,16 +16,14 @@ * along with this program. If not, see . */ -.pragma library - -.import "common.js" as Common -.import "../utils.js" as Utils -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { textsub } from "../utils.mjs" +import { API as Common, ExecutableObject } from "common.mjs" +import { parseDomain, Expression, SpecialDomain } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" -class Function extends Common.ExecutableObject { +export default class Function extends ExecutableObject { static type(){return 'Function'} static displayType(){return qsTr('Function')} static displayTypeMultiple(){return qsTr('Functions')} @@ -54,11 +52,11 @@ class Function extends Common.ExecutableObject { drawPoints = true, drawDashedLines = true) { if(name == null) name = Common.getNewName('fghjqlmnopqrstuvwabcde') super(name, visible, color, labelContent) - if(typeof expression == 'number' || typeof expression == 'string') expression = new MathLib.Expression(expression.toString()) + if(typeof expression == 'number' || typeof expression == 'string') expression = new Expression(expression.toString()) this.expression = expression - if(typeof definitionDomain == 'string') definitionDomain = MathLib.parseDomain(definitionDomain) + if(typeof definitionDomain == 'string') definitionDomain = parseDomain(definitionDomain) this.definitionDomain = definitionDomain - if(typeof destinationDomain == 'string') destinationDomain = MathLib.parseDomain(destinationDomain) + if(typeof destinationDomain == 'string') destinationDomain = parseDomain(destinationDomain) this.destinationDomain = destinationDomain this.displayMode = displayMode this.labelPosition = labelPosition @@ -68,15 +66,15 @@ class Function extends Common.ExecutableObject { } getReadableString() { - if(this.displayMode == 'application') { + if(this.displayMode === 'application') { return `${this.name}: ${this.definitionDomain} ⟶ ${this.destinationDomain}\n ${' '.repeat(this.name.length)}x ⟼ ${this.expression.toString()}` } else { - return `${this.name}(x) = ${this.expression.toString()}\nD${Utils.textsub(this.name)} = ${this.definitionDomain}` + return `${this.name}(x) = ${this.expression.toString()}\nD${textsub(this.name)} = ${this.definitionDomain}` } } getLatexString() { - if(this.displayMode == 'application') { + if(this.displayMode === 'application') { return `${Latex.variable(this.name)}:\\begin{array}{llll}${this.definitionDomain.latexMarkup}\\textrm{ } & \\rightarrow & \\textrm{ }${this.destinationDomain.latexMarkup}\\\\ x\\textrm{ } & \\mapsto & \\textrm{ }${this.expression.latexMarkup}\\end{array}` } else { @@ -111,14 +109,16 @@ class Function extends Common.ExecutableObject { // Label this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } - + + /** + * Reusable in other objects. + * Drawing small traits every few pixels + */ static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { - // Reusable in other objects. - // Drawing small traits every 0.2px - var pxprecision = 10 - var previousX = canvas.px2x(0) - var previousY = null; - if(definitionDomain instanceof MathLib.SpecialDomain && definitionDomain.moveSupported) { + let pxprecision = 10 + let previousX = canvas.px2x(0) + let previousY = null; + if(definitionDomain instanceof SpecialDomain && definitionDomain.moveSupported) { // Point based functions. previousX = definitionDomain.next(previousX) if(previousX === null) previousX = definitionDomain.next(canvas.px2x(0)) @@ -126,8 +126,8 @@ class Function extends Common.ExecutableObject { if(!drawPoints && !drawDash) return while(previousX !== null && canvas.x2px(previousX) < canvas.canvasSize.width) { // Reconverted for canvas to fix for logarithmic scales. - var currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX)+pxprecision)); - var currentY = expr.execute(currentX) + let currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX)+pxprecision)); + let currentY = expr.execute(currentX) if(currentX === null) break; if((definitionDomain.includes(currentX) || definitionDomain.includes(previousX)) && (destinationDomain.includes(currentY) || destinationDomain.includes(previousY))) { @@ -173,7 +173,7 @@ class Function extends Common.ExecutableObject { do { tmpPx--; currentX = canvas.px2x(tmpPx) - } while(!definitionDomain.includes(currentX) && currentX != previousX) + } while(!definitionDomain.includes(currentX) && currentX !== previousX) } // This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...) let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.canvasSize.height)) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs similarity index 67% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs index 9604656..696084d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs @@ -16,19 +16,19 @@ * along with this program. If not, see . */ -.pragma library +import { parseDomain, executeExpression, Expression, EmptySet, Domain } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "function.js" as F -.import "../objects.js" as Objects -.import "../utils.js" as Utils -.import "../mathlib.js" as MathLib -.import "../historylib.js" as HistoryLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, ExecutableObject } from "common.mjs" +import Function from "function.mjs" + +import { API as HistoryAPI } from "../history/common.mjs" +import { CreateNewObject } from "../historylib.mjs" -class GainBode extends Common.ExecutableObject { +export default class GainBode extends ExecutableObject { static type(){return 'Gain Bode'} static displayType(){return qsTr('Bode Magnitude')} static displayTypeMultiple(){return qsTr('Bode Magnitudes')} @@ -44,7 +44,7 @@ class GainBode extends Common.ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', pass = 'high', gain = '20', labelPosition = 'above', labelX = 1, omGraduation = false) { if(name == null) name = Common.getNewName('G') - if(name == 'G') name = 'G₀' // G is reserved for sum of BODE magnitudes (Somme gains Bode). + if(name === 'G') name = 'G₀' // G is reserved for sum of BODE magnitudes (Somme gains Bode). super(name, visible, color, labelContent) if(typeof om_0 == "string") { // Point name or create one @@ -52,7 +52,7 @@ class GainBode extends Common.ExecutableObject { if(om_0 == null) { // Create new point om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), true, this.color, 'name']) - HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export())) + HistoryAPI.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) om_0.update() labelPosition = 'below' } @@ -60,7 +60,7 @@ class GainBode extends Common.ExecutableObject { } this.om_0 = om_0 this.pass = pass - if(typeof gain == 'number' || typeof gain == 'string') gain = new MathLib.Expression(gain.toString()) + if(typeof gain == 'number' || typeof gain == 'string') gain = new Expression(gain.toString()) this.gain = gain this.labelPosition = labelPosition this.labelX = labelX @@ -68,12 +68,12 @@ class GainBode extends Common.ExecutableObject { } getReadableString() { - let pass = this.pass == "low" ? qsTr("low-pass") : qsTr("high-pass"); + let pass = this.pass === "low" ? qsTr("low-pass") : qsTr("high-pass"); return `${this.name}: ${pass}; ${this.om_0.name} = ${this.om_0.x}\n ${' '.repeat(this.name.length)}${this.gain.toString(true)} dB/dec` } getLatexString() { - let pass = this.pass == "low" ? qsTr("low-pass") : qsTr("high-pass"); + let pass = this.pass === "low" ? qsTr("low-pass") : qsTr("high-pass"); return `\\mathrm{${Latex.variable(this.name)}:}\\begin{array}{l} \\textsf{${pass}};${Latex.variable(this.om_0.name)} = ${this.om_0.x.latexMarkup} \\\\ ${this.gain.latexMarkup}\\textsf{ dB/dec} @@ -86,9 +86,9 @@ class GainBode extends Common.ExecutableObject { } execute(x=1) { - if(typeof x == 'string') x = MathLib.executeExpression(x) - if((this.pass == 'high' && x < this.om_0.x) || (this.pass == 'low' && x > this.om_0.x)) { - var dbfn = new MathLib.Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) + if(typeof x == 'string') x = executeExpression(x) + if((this.pass === 'high' && x < this.om_0.x) || (this.pass === 'low' && x > this.om_0.x)) { + let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) return dbfn.execute(x) } else { return this.om_0.y.execute() @@ -96,10 +96,10 @@ class GainBode extends Common.ExecutableObject { } simplify(x = 1) { - var xval = x - if(typeof x == 'string') xval = MathLib.executeExpression(x) - if((this.pass == 'high' && xval < this.om_0.x) || (this.pass == 'low' && xval > this.om_0.x)) { - var dbfn = new MathLib.Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) + let xval = x + if(typeof x == 'string') xval = executeExpression(x) + if((this.pass === 'high' && xval < this.om_0.x) || (this.pass === 'low' && xval > this.om_0.x)) { + let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) return dbfn.simplify(x) } else { return this.om_0.y.toString() @@ -111,20 +111,20 @@ class GainBode extends Common.ExecutableObject { } draw(canvas, ctx) { - var base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)] - var dbfn = new MathLib.Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`) - var inDrawDom = new MathLib.EmptySet() + let base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)] + let dbfn = new Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`) + let inDrawDom = new EmptySet() - if(this.pass == 'high') { - // High pass, linear line from begining, then constant to the end. + if(this.pass === 'high') { + // High pass, linear line from beginning, then constant to the end. canvas.drawLine(ctx, base[0], base[1], canvas.canvasSize.width, base[1]) - inDrawDom = MathLib.parseDomain(`]-inf;${this.om_0.x}[`) + inDrawDom = parseDomain(`]-inf;${this.om_0.x}[`) } else { // Low pass, constant from the beginning, linear line to the end. canvas.drawLine(ctx, base[0], base[1], 0, base[1]) - inDrawDom = MathLib.parseDomain(`]${this.om_0.x};+inf[`) + inDrawDom = parseDomain(`]${this.om_0.x};+inf[`) } - F.Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R) + Function.drawFunction(canvas, ctx, dbfn, inDrawDom, Domain.R) // Dashed line representing break in function var xpos = canvas.x2px(this.om_0.x.execute()) var dashPxSize = 10 @@ -137,7 +137,7 @@ class GainBode extends Common.ExecutableObject { update() { super.update() - if(Objects.currentObjects['Somme gains Bode'] != undefined && Objects.currentObjects['Somme gains Bode'].length > 0) { + if(Objects.currentObjects['Somme gains Bode'] !== undefined && Objects.currentObjects['Somme gains Bode'].length > 0) { Objects.currentObjects['Somme gains Bode'][0].recalculateCache() } else { Objects.createNewRegisteredObject('Somme gains Bode') diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs similarity index 76% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index edf9d68..14ff351 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -16,17 +16,17 @@ * along with this program. If not, see . */ -.pragma library +import { executeExpression, Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../historylib.js" as HistoryLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, ExecutableObject } from "common.mjs" +import { API as HistoryAPI } from "../history/common.mjs" +import { CreateNewObject } from "../historylib.mjs" -class PhaseBode extends Common.ExecutableObject { +export default class PhaseBode extends ExecutableObject { static type(){return 'Phase Bode'} static displayType(){return qsTr('Bode Phase')} static displayTypeMultiple(){return qsTr('Bode Phases')} @@ -41,9 +41,9 @@ class PhaseBode extends Common.ExecutableObject { constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', phase = 90, unit = '°', labelPosition = 'above', labelX = 1) { if(name == null) name = Common.getNewName('φ') - if(name == 'φ') name = 'φ₀' // φ is reserved for sum of BODE phases (Somme phases Bode). + if(name === 'φ') name = 'φ₀' // φ is reserved for sum of BODE phases (Somme phases Bode). super(name, visible, color, labelContent) - if(typeof phase == 'number' || typeof phase == 'string') phase = new MathLib.Expression(phase.toString()) + if(typeof phase == 'number' || typeof phase == 'string') phase = new Expression(phase.toString()) this.phase = phase if(typeof om_0 == "string") { // Point name or create one @@ -52,7 +52,7 @@ class PhaseBode extends Common.ExecutableObject { // Create new point om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), this.color, 'name']) om_0.labelPosition = this.phase.execute() >= 0 ? 'above' : 'below' - HistoryLib.history.addToHistory(new HistoryLib.CreateNewObject(om_0.name, 'Point', om_0.export())) + HistoryAPI.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) labelPosition = 'below' } om_0.requiredBy.push(this) @@ -77,7 +77,7 @@ class PhaseBode extends Common.ExecutableObject { } execute(x=1) { - if(typeof x == 'string') x = MathLib.executeExpression(x) + if(typeof x == 'string') x = executeExpression(x) if(x < this.om_0.x) { return this.om_0.y.execute() } else { @@ -86,13 +86,13 @@ class PhaseBode extends Common.ExecutableObject { } simplify(x = 1) { - var xval = x - if(typeof x == 'string') xval = MathLib.executeExpression(x) + let xval = x + if(typeof x == 'string') xval = executeExpression(x) if(xval < this.om_0.x) { return this.om_0.y.toString() } else { - var newExp = this.om_0.y.toEditableString() + ' + ' + this.phase.toEditableString() - return (new MathLib.Expression(newExp)).toString() + let newExp = this.om_0.y.toEditableString() + ' + ' + this.phase.toEditableString() + return (new Expression(newExp)).toString() } } @@ -101,11 +101,11 @@ class PhaseBode extends Common.ExecutableObject { } draw(canvas, ctx) { - var baseX = canvas.x2px(this.om_0.x.execute()) - var omy = this.om_0.y.execute() - var augmt = this.phase.execute() - var baseY = canvas.y2px(omy) - var augmtY = canvas.y2px(omy+augmt) + let baseX = canvas.x2px(this.om_0.x.execute()) + let omy = this.om_0.y.execute() + let augmt = this.phase.execute() + let baseY = canvas.y2px(omy) + let augmtY = canvas.y2px(omy+augmt) // Before change line. canvas.drawLine(ctx, 0, baseY, Math.min(baseX, canvas.canvasSize.height), baseY) // Transition line. @@ -118,7 +118,7 @@ class PhaseBode extends Common.ExecutableObject { } update() { - if(Objects.currentObjects['Somme phases Bode'] != undefined && Objects.currentObjects['Somme phases Bode'].length > 0) { + if(Objects.currentObjects['Somme phases Bode'] !== undefined && Objects.currentObjects['Somme phases Bode'].length > 0) { Objects.currentObjects['Somme phases Bode'][0].recalculateCache() } else { Objects.createNewRegisteredObject('Somme phases Bode') diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs similarity index 91% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index effdee1..d03053d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -16,15 +16,13 @@ * along with this program. If not, see . */ -.pragma library - -.import "common.js" as Common -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" +import { API as Common, DrawableObject } from "common.mjs" -class Point extends Common.DrawableObject { +export default class Point extends DrawableObject { static type(){return 'Point'} static displayType(){return qsTr('Point')} static displayTypeMultiple(){return qsTr('Points')} @@ -40,9 +38,9 @@ class Point extends Common.DrawableObject { x = 1, y = 0, labelPosition = 'above', pointStyle = '●') { if(name == null) name = Common.getNewName('ABCDEFJKLMNOPQRSTUVW') super(name, visible, color, labelContent) - if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) + if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) this.x = x - if(typeof y == 'number' || typeof y == 'string') y = new MathLib.Expression(y.toString()) + if(typeof y == 'number' || typeof y == 'string') y = new Expression(y.toString()) this.y = y this.labelPosition = labelPosition this.pointStyle = pointStyle diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs similarity index 92% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index e872876..32105d1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -16,14 +16,12 @@ * along with this program. If not, see . */ -.pragma library - -.import "common.js" as Common -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, ExecutableObject } from "common.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" -class RepartitionFunction extends Common.ExecutableObject { +export default class RepartitionFunction extends ExecutableObject { static type(){return 'Repartition'} static displayType(){return qsTr('Repartition')} static displayTypeMultiple(){return qsTr('Repartition functions')} @@ -34,7 +32,7 @@ class RepartitionFunction extends Common.ExecutableObject { 'comment', 'Note: Specify the probability for each value.' ), - [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d\.,]+$/, 'P({name_} = ', ') = '), + [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d.,]+$/, 'P({name_} = ', ') = '), }} constructor(name = null, visible = true, color = null, labelContent = 'name + value', @@ -69,7 +67,7 @@ class RepartitionFunction extends Common.ExecutableObject { } execute(x = 1) { - var ret = 0; + let ret = 0; Object.keys(this.probabilities).sort((a,b) => a-b).forEach(idx => { if(x >= idx) ret += parseFloat(this.probabilities[idx].replace(/,/g, '.')) }) @@ -77,6 +75,7 @@ class RepartitionFunction extends Common.ExecutableObject { } canExecute(x = 1) {return true} + // Simplify returns the simplified string of the expression. simplify(x = 1) { return this.execute(x) @@ -94,8 +93,8 @@ class RepartitionFunction extends Common.ExecutableObject { } draw(canvas, ctx) { - var currentY = 0; - var keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b) + let currentY = 0; + let keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b) if(canvas.isVisible(keys[0],this.probabilities[keys[0]].replace(/,/g, '.'))) { canvas.drawLine(ctx, 0, @@ -109,8 +108,8 @@ class RepartitionFunction extends Common.ExecutableObject { ctx.stroke(); } } - for(var i = 0; i < keys.length-1; i++) { - var idx = keys[i]; + for(let i = 0; i < keys.length-1; i++) { + let idx = keys[i]; currentY += parseFloat(this.probabilities[idx].replace(/,/g, '.')); if(canvas.isVisible(idx,currentY) || canvas.isVisible(keys[i+1],currentY)) { canvas.drawLine(ctx, diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs similarity index 78% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index c08aac8..4e06b56 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -16,16 +16,15 @@ * along with this program. If not, see . */ -.pragma library +import { Sequence as MathSequence, Domain } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "function.js" as F -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, ExecutableObject } from "common.mjs" +import Function from "function.mjs" -class Sequence extends Common.ExecutableObject { +export default class Sequence extends ExecutableObject { static type(){return 'Sequence'} static displayType(){return qsTr('Sequence')} static displayTypeMultiple(){return qsTr('Sequences')} @@ -59,18 +58,21 @@ class Sequence extends Common.ExecutableObject { export() { return [this.name, this.visible, this.color.toString(), this.labelContent, - this.drawPoints, this.drawDashedLines, this.defaultExpression, this.baseValues, this.labelPosition, this.labelX] + this.drawPoints, this.drawDashedLines, this.defaultExpression, this.baseValues, + this.labelPosition, this.labelX] } update() { + console.log('Updating sequence', this.sequence) + console.trace() super.update() if( - this.sequence == null || this.baseValues != this.sequence.baseValues || - this.sequence.name != this.name || - this.sequence.expr != Object.values(this.defaultExpression)[0] || - this.sequence.valuePlus != Object.keys(this.defaultExpression)[0] + this.sequence == null || this.baseValues !== this.sequence.baseValues || + this.sequence.name !== this.name || + this.sequence.expr !== Object.values(this.defaultExpression)[0] || + this.sequence.valuePlus !== Object.keys(this.defaultExpression)[0] ) - this.sequence = new MathLib.Sequence( + this.sequence = new MathSequence( this.name, this.baseValues, Object.keys(this.defaultExpression)[0], Object.values(this.defaultExpression)[0] @@ -86,15 +88,15 @@ class Sequence extends Common.ExecutableObject { } execute(x = 1) { - if(x % 1 == 0) + if(x % 1 === 0) return this.sequence.execute(x) return null } - canExecute(x = 1) {return x%1 == 0} + canExecute(x = 1) {return x%1 === 0} // Simplify returns the simplified string of the expression. simplify(x = 1) { - if(x % 1 == 0) + if(x % 1 === 0) return this.sequence.simplify(x) return null } @@ -122,7 +124,7 @@ class Sequence extends Common.ExecutableObject { } draw(canvas, ctx) { - F.Function.drawFunction(canvas, ctx, this.sequence, canvas.logscalex ? MathLib.Domain.NE : MathLib.Domain.N, MathLib.Domain.R, this.drawPoints, this.drawDashedLines) + Function.drawFunction(canvas, ctx, this.sequence, canvas.logscalex ? Domain.NE : Domain.N, Domain.R, this.drawPoints, this.drawDashedLines) // Label this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs similarity index 72% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs index f8b3fee..e03ca81 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs @@ -16,17 +16,16 @@ * along with this program. If not, see . */ -.pragma library +import { parseDomain, Expression, Domain } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "function.js" as F -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { ExecutableObject } from "common.mjs" +import Function from "function.mjs" -class SommeGainsBode extends Common.ExecutableObject { +export default class SommeGainsBode extends ExecutableObject { static type(){return 'Somme gains Bode'} static displayType(){return qsTr('Bode Magnitudes Sum')} static displayTypeMultiple(){return qsTr('Bode Magnitudes Sum')} @@ -58,7 +57,7 @@ class SommeGainsBode extends Common.ExecutableObject { } execute(x = 0) { - for(var [dbfn, inDrawDom] of this.cachedParts) { + for(let [dbfn, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { return dbfn.execute(x) } @@ -71,7 +70,7 @@ class SommeGainsBode extends Common.ExecutableObject { } simplify(x = 1) { - for(var [dbfn, inDrawDom] of this.cachedParts) { + for(let [dbfn, inDrawDom] of this.cachedParts) { if(inDrawDom.includes(x)) { return dbfn.simplify(x) } @@ -82,33 +81,33 @@ class SommeGainsBode extends Common.ExecutableObject { recalculateCache() { this.cachedParts = [] // Calculating this is fairly resource expansive so it's cached. - if(Objects.currentObjects['Gain Bode'] != undefined) { + if(Objects.currentObjects['Gain Bode'] !== undefined) { console.log('Recalculating cache gain') // Minimum to draw (can be expended if needed, just not infinite or it'll cause issues. - var drawMin = 0.001 + let drawMin = 0.001 - var baseY = 0 - var om0xGains = {1000000000: 0} // To draw the last part - var om0xPass = {1000000000: 'high'} // To draw the last part + let baseY = 0 + let om0xGains = {1000000000: 0} // To draw the last part + let om0xPass = {1000000000: 'high'} // To draw the last part Objects.currentObjects['Gain Bode'].forEach(function(gainObj) { // Sorting by their om_0 position. - var om0x = gainObj.om_0.x.execute() - if(om0xGains[om0x] == undefined) { + let om0x = gainObj.om_0.x.execute() + if(om0xGains[om0x] === undefined) { om0xGains[om0x] = gainObj.gain.execute() - om0xPass[om0x] = gainObj.pass == 'high' + om0xPass[om0x] = gainObj.pass === 'high' } else { om0xGains[om0x+0.001] = gainObj.gain.execute() - om0xPass[om0x+0.001] = gainObj.pass == 'high' + om0xPass[om0x+0.001] = gainObj.pass === 'high' } baseY += gainObj.execute(drawMin) }) // Sorting the om_0x - var om0xList = Object.keys(om0xGains).map(x => parseFloat(x)) // THEY WERE CONVERTED TO STRINGS... + let om0xList = Object.keys(om0xGains).map(x => parseFloat(x)) // THEY WERE CONVERTED TO STRINGS... om0xList.sort((a,b) => a - b) // Adding the total gains. - var gainsBeforeP = [] - var gainsAfterP = [] - var gainTotal = 0 - for(var om0x of om0xList){ + let gainsBeforeP = [] + let gainsAfterP = [] + let gainTotal = 0 + for(let om0x of om0xList){ if(om0xPass[om0x]) { // High-pass gainsBeforeP.push(om0xGains[om0x]) gainsAfterP.push(0) @@ -119,10 +118,10 @@ class SommeGainsBode extends Common.ExecutableObject { } } // Calculating parts - var previousPallier = drawMin - for(var pallier = 0; pallier < om0xList.length; pallier++) { - var dbfn = new MathLib.Expression(`${gainTotal}*(ln(x)-ln(${previousPallier}))/ln(10)+${baseY}`) - var inDrawDom = MathLib.parseDomain(`]${previousPallier};${om0xList[pallier]}]`) + let previousPallier = drawMin + for(let pallier = 0; pallier < om0xList.length; pallier++) { + let dbfn = new Expression(`${gainTotal}*(ln(x)-ln(${previousPallier}))/ln(10)+${baseY}`) + let inDrawDom = parseDomain(`]${previousPallier};${om0xList[pallier]}]`) this.cachedParts.push([dbfn, inDrawDom]) previousPallier = om0xList[pallier] baseY = dbfn.execute(om0xList[pallier]) @@ -133,8 +132,8 @@ class SommeGainsBode extends Common.ExecutableObject { draw(canvas, ctx) { if(this.cachedParts.length > 0) { - for(var [dbfn, inDrawDom] of this.cachedParts) { - F.Function.drawFunction(canvas, ctx, dbfn, inDrawDom, MathLib.Domain.R) + for(let [dbfn, inDrawDom] of this.cachedParts) { + Function.drawFunction(canvas, ctx, dbfn, inDrawDom, Domain.R) if(inDrawDom.includes(this.labelX)) { // Label this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs similarity index 74% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs index eb1c3e0..328c069 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs @@ -16,16 +16,14 @@ * along with this program. If not, see . */ -.pragma library +import { executeExpression, Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Objects from "../objects.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { ExecutableObject } from "common.mjs" - -class SommePhasesBode extends Common.ExecutableObject { +export default class SommePhasesBode extends ExecutableObject { static type(){return 'Somme phases Bode'} static displayType(){return qsTr('Bode Phases Sum')} static displayTypeMultiple(){return qsTr('Bode Phases Sum')} @@ -57,18 +55,18 @@ class SommePhasesBode extends Common.ExecutableObject { } execute(x=1) { - if(typeof x == 'string') x = MathLib.executeExpression(x) - for(var i = 0; i < this.om0xList.length-1; i++) { + if(typeof x == 'string') x = executeExpression(x) + for(let i = 0; i < this.om0xList.length-1; i++) { if(x >= this.om0xList[i] && x < this.om0xList[i+1]) return this.phasesList[i] } } simplify(x = 1) { - var xval = x - if(typeof x == 'string') xval = MathLib.executeExpression(x) - for(var i = 0; i < this.om0xList.length-1; i++) { + let xval = x + if(typeof x == 'string') xval = executeExpression(x) + for(let i = 0; i < this.om0xList.length-1; i++) { if(xval >= this.om0xList[i] && xval < this.om0xList[i+1]) { - return (new MathLib.Expression(this.phasesExprList[i])).simplify() + return (new Expression(this.phasesExprList[i])).simplify() } } return '0' @@ -80,20 +78,20 @@ class SommePhasesBode extends Common.ExecutableObject { recalculateCache() { // Minimum to draw (can be expended if needed, just not infinite or it'll cause issues. - var drawMin = 0.001 - var drawMax = 100000 + let drawMin = 0.001 + let drawMax = 100000 this.om0xList = [drawMin, drawMax] this.phasesList = [0] this.phasesExprList = ['0'] - var phasesDict = {} - var phasesExprDict = {} + let phasesDict = {} + let phasesExprDict = {} phasesDict[drawMax] = 0 - if(Objects.currentObjects['Phase Bode'] != undefined) { + if(Objects.currentObjects['Phase Bode'] !== undefined) { console.log('Recalculating cache phase') - for(var obj of Objects.currentObjects['Phase Bode']) { + for(let obj of Objects.currentObjects['Phase Bode']) { this.om0xList.push(obj.om_0.x.execute()) - if(phasesDict[obj.om_0.x.execute()] == undefined) { + if(phasesDict[obj.om_0.x.execute()] === undefined) { phasesDict[obj.om_0.x.execute()] = obj.phase.execute() phasesExprDict[obj.om_0.x.execute()] = obj.phase.toEditableString() } else { @@ -104,8 +102,8 @@ class SommePhasesBode extends Common.ExecutableObject { this.phasesExprList[0] += '+' + obj.om_0.y.toEditableString() } this.om0xList.sort((a,b) => a - b) - var totalAdded = this.phasesList[0] - for(var i = 1; i < this.om0xList.length; i++) { + let totalAdded = this.phasesList[0] + for(let i = 1; i < this.om0xList.length; i++) { this.phasesList[i] = this.phasesList[i-1] + phasesDict[this.om0xList[i]] this.phasesExprList[i] = this.phasesExprList[i-1] + '+' + phasesDict[this.om0xList[i]] } @@ -113,11 +111,11 @@ class SommePhasesBode extends Common.ExecutableObject { } draw(canvas, ctx) { - for(var i = 0; i < this.om0xList.length-1; i++) { - var om0xBegin = canvas.x2px(this.om0xList[i]) - var om0xEnd = canvas.x2px(this.om0xList[i+1]) - var baseY = canvas.y2px(this.phasesList[i]) - var nextY = canvas.y2px(this.phasesList[i+1]) + for(let i = 0; i < this.om0xList.length-1; i++) { + let om0xBegin = canvas.x2px(this.om0xList[i]) + let om0xEnd = canvas.x2px(this.om0xList[i+1]) + let baseY = canvas.y2px(this.phasesList[i]) + let nextY = canvas.y2px(this.phasesList[i+1]) canvas.drawLine(ctx, om0xBegin, baseY, om0xEnd, baseY) canvas.drawLine(ctx, om0xEnd, baseY, om0xEnd, nextY) } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs similarity index 92% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index b513ea2..040e7bd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -16,16 +16,14 @@ * along with this program. If not, see . */ -.pragma library +import { Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" -.import "common.js" as Common -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, DrawableObject } from "common.mjs" - -class Text extends Common.DrawableObject { +export default class Text extends DrawableObject { static type(){return 'Text'} static displayType(){return qsTr('Text')} static displayTypeMultiple(){return qsTr('Texts')} @@ -45,9 +43,9 @@ class Text extends Common.DrawableObject { x = 1, y = 0, labelPosition = 'center', text = 'New text', disableLatex = false) { if(name == null) name = Common.getNewName('t') super(name, visible, color, labelContent) - if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) + if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) this.x = x - if(typeof y == 'number' || typeof y == 'string') y = new MathLib.Expression(y.toString()) + if(typeof y == 'number' || typeof y == 'string') y = new Expression(y.toString()) this.y = y this.labelPosition = labelPosition this.text = text diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs similarity index 95% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index cea2864..036c408 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -16,17 +16,15 @@ * along with this program. If not, see . */ -.pragma library +import { Expression } from "../mathlib.mjs" +import * as P from "../parameters.mjs" +import Latex from "../math/latex.mjs" +import Objects from "../objects.mjs" -.import "common.js" as Common -.import "../objects.js" as Objects -.import "../mathlib.js" as MathLib -.import "../parameters.js" as P -.import "../math/latex.js" as Latex +import { API as Common, DrawableObject } from "common.mjs" - -class XCursor extends Common.DrawableObject { +export default class XCursor extends DrawableObject { static type(){return 'X Cursor'} static displayType(){return qsTr('X Cursor')} static displayTypeMultiple(){return qsTr('X Cursors')} @@ -51,7 +49,7 @@ class XCursor extends Common.DrawableObject { super(name, visible, color, labelContent) this.approximate = approximate this.rounding = rounding - if(typeof x == 'number' || typeof x == 'string') x = new MathLib.Expression(x.toString()) + if(typeof x == 'number' || typeof x == 'string') x = new Expression(x.toString()) this.x = x this.targetElement = targetElement if(typeof targetElement == "string") { @@ -171,7 +169,7 @@ class XCursor extends Common.DrawableObject { (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, textSize.height+5)) // Drawing label at the position of the target element. - if(this.targetValuePosition == 'Next to target' && this.targetElement != null) { + if(this.targetValuePosition === 'Next to target' && this.targetElement != null) { let ypos = canvas.y2px(this.targetElement.execute(this.x.execute())) this.drawLabel(canvas, ctx, this.labelPosition, xpos, ypos, false, this.getTargetValueLatexLabel.bind(this), this.getTargetValueLabel.bind(this), diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs similarity index 96% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 2ef194a..2cf28a3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -class Expression { +export class Expression { constructor(...variables) { this.type = 'Expression' this.variables = variables @@ -27,7 +27,7 @@ class Expression { } } -class Enum { +export class Enum { constructor(...values) { this.type = 'Enum' this.values = values @@ -39,7 +39,7 @@ class Enum { } } -class ObjectType { +export class ObjectType { constructor(objType) { this.type = 'ObjectType' this.objType = objType @@ -50,7 +50,7 @@ class ObjectType { } } -class List { +export class List { constructor(type, format = /^.+$/, label = '', forbidAdding = false) { // type can be string, int and double. this.type = 'List' @@ -65,7 +65,7 @@ class List { } } -class Dictionary { +export class Dictionary { constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ', forbidAdding = false) { // type & keyType can be string, int and double. this.type = 'Dict' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md index a0ff7e7..8fa8a93 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/README.md @@ -2,4 +2,4 @@ Here lies the potential new, abandoned, cleaner implementation of the parsing system that was supposed to replace expr-eval.js, but never came to be because it's unfinished. If somebody has the will to finish this, you're welcome to try, as I won't. -Currently, the tokenizer is complete in use to provide tokens for the syntax highlighting. +Currently, the tokenizer is complete in use to provide tokens for the syntax highlighting, and the reference to provide usage. diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs similarity index 93% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs index 53a5941..3313a1b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/common.mjs @@ -16,9 +16,8 @@ * along with this program. If not, see . */ -.pragma library -class InputExpression { +export default class InputExpression { constructor(expression) { this.position = 0; this.input = expression; @@ -33,7 +32,7 @@ class InputExpression { } skip(char) { - if(!this.atEnd() && this.peek() == char) { + if(!this.atEnd() && this.peek() === char) { this.position++; } else { this.raise("Unexpected character " + this.peek() + ". Expected character " + char); diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs similarity index 60% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs index b2cc6bc..71d34d1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/parsing.mjs @@ -16,19 +16,17 @@ * along with this program. If not, see . */ -.pragma library +import * as Reference from "reference.mjs" +import * as T from "./tokenizer.mjs" +import InputExpression from "common.mjs" -.import "reference.js" as Reference -.import "tokenizer.js" as TK -.import "common.js" as Common +export const Input = InputExpression +export const TokenType = T.TokenType +export const Token = T.Token +export const Tokenizer = T.ExpressionTokenizer -var Input = Common.InputExpression -var TokenType = TK.TokenType -var Token = TK.Token -var Tokenizer = TK.ExpressionTokenizer - -var FUNCTIONS_LIST = Reference.FUNCTIONS_LIST -var FUNCTIONS = Reference.FUNCTIONS -var FUNCTIONS_USAGE = Reference.FUNCTIONS_USAGE -var CONSTANTS_LIST = Reference.CONSTANTS_LIST -var CONSTANTS = Reference.CONSTANTS +export const FUNCTIONS_LIST = Reference.FUNCTIONS_LIST +export const FUNCTIONS = Reference.FUNCTIONS +export const FUNCTIONS_USAGE = Reference.FUNCTIONS_USAGE +export const CONSTANTS_LIST = Reference.CONSTANTS_LIST +export const CONSTANTS = Reference.CONSTANTS diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs similarity index 88% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs index df880c5..ac845ce 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/polyfill.mjs @@ -17,10 +17,7 @@ */ // Contains polyfill math functions used for reference. - -.pragma library - -function factorial(x) { +export function factorial(x) { if (x < 0) // Integrating by less than 0 if(isFinite(n)) return Infinity @@ -43,7 +40,7 @@ let GAMMA_P = [ 0.36899182659531622704e-5 ] -function gamma(n) { +export function gamma(n) { if(n <= 0) // Integrating by less than 0 if(isFinite(n)) return Infinity @@ -91,7 +88,7 @@ function gamma(n) { return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x } -function arrayMap(f, arr) { +export function arrayMap(f, arr) { if (typeof f != 'function') throw new EvalError(qsTranslate('error', 'First argument to map is not a function.')) if (!Array.isArray(arr)) @@ -99,7 +96,7 @@ function arrayMap(f, arr) { return arr.map(f) } -function arrayFold(f, init, arr) { +export function arrayFold(f, init, arr) { if (typeof f != 'function') throw new EvalError(qsTranslate('error', 'First argument to fold is not a function.')) if (!Array.isArray(arr)) @@ -107,7 +104,7 @@ function arrayFold(f, init, arr) { return arr.reduce(f, init) } -function arrayFilter(f, arr) { +export function arrayFilter(f, arr) { if (typeof f != 'function') throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')) if (!Array.isArray(arr)) @@ -115,21 +112,13 @@ function arrayFilter(f, arr) { return arr.filter(f) } -function arrayFilter(f, arr) { - if (typeof f != 'function') - throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.')) - if (!Array.isArray(arr)) - throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.')) - return arr.filter(f) -} - -function arrayJoin(sep, arr) { +export function arrayJoin(sep, arr) { if (!Array.isArray(arr)) throw new Error(qsTranslate('error', 'Second argument to join is not an array.')) return arr.join(sep) } -function indexOf(target, s) { +export function indexOf(target, s) { if (!(Array.isArray(s) || typeof s === 'string')) throw new Error(qsTranslate('error', 'Second argument to indexOf is not a string or array.')) return s.indexOf(target) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs similarity index 91% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs index 5d1cb9f..d6ce9dc 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/reference.mjs @@ -16,12 +16,9 @@ * along with this program. If not, see . */ -.pragma library +import * as Polyfill from "polyfill.mjs" -.import "polyfill.js" as Polyfill - - -const CONSTANTS = { +export const CONSTANTS = { "π": Math.PI, "pi": Math.PI, "inf": Infinity, @@ -29,9 +26,9 @@ const CONSTANTS = { "∞": Infinity, "e": Math.E }; -const CONSTANTS_LIST = Object.keys(CONSTANTS); +export const CONSTANTS_LIST = Object.keys(CONSTANTS); -const FUNCTIONS = { +export const FUNCTIONS = { // The functions commented are the one either not implemented // in the parser, or not to be used for autocompletion. // Unary operators @@ -94,9 +91,9 @@ const FUNCTIONS = { 'integral': () => 0, // TODO: Implement 'derivative': () => 0, } -const FUNCTIONS_LIST = Object.keys(FUNCTIONS); +export const FUNCTIONS_LIST = Object.keys(FUNCTIONS); -class P { +export class P { // Parameter class. constructor(type, name = '', optional = false, multipleAllowed = false) { this.name = name @@ -107,7 +104,7 @@ class P { toString() { let base_string = this.type - if(this.name != '') + if(this.name !== '') base_string = `${this.name}: ${base_string}` if(this.multipleAllowed) base_string += '...' @@ -119,12 +116,12 @@ class P { } } -let string = new P('string') -let bool = new P('bool') -let number = new P('number') -let array = new P('array') +export let string = new P('string') +export let bool = new P('bool') +export let number = new P('number') +export let array = new P('array') -const FUNCTIONS_USAGE = { +export const FUNCTIONS_USAGE = { 'length': [string], 'not': [bool], // Math functions diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs similarity index 84% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs index 9a907fa..bad6e7e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parsing/tokenizer.mjs @@ -16,18 +16,17 @@ * along with this program. If not, see . */ -.pragma library -.import "reference.js" as Reference +import * as Reference from "reference.mjs" const WHITESPACES = " \t\n\r" -const STRING_LIMITORS = '"\'`'; +const STRING_LIMITERS = '"\'`'; const OPERATORS = "+-*/^%?:=!><"; -const PUNCTUTATION = "()[]{},."; +const PUNCTUATION = "()[]{},."; const NUMBER_CHARS = "0123456789" const IDENTIFIER_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789_₀₁₂₃₄₅₆₇₈₉αβγδεζηθκλμξρςστφχψωₐₑₒₓₔₕₖₗₘₙₚₛₜ" -var TokenType = { +export const TokenType = { // Expression type "WHITESPACE": "WHITESPACE", "VARIABLE": "VARIABLE", @@ -40,7 +39,7 @@ var TokenType = { "UNKNOWN": "UNKNOWN" } -class Token { +export class Token { constructor(type, value, startPosition) { this.type = type; this.value = value; @@ -48,7 +47,13 @@ class Token { } } -class ExpressionTokenizer { +export class ExpressionTokenizer { + /** + * + * @param {InputExpression} input + * @param {boolean} tokenizeWhitespaces + * @param {boolean} errorOnUnknown + */ constructor(input, tokenizeWhitespaces = false, errorOnUnknown = true) { this.input = input; this.currentToken = null; @@ -71,12 +76,12 @@ class ExpressionTokenizer { readString() { let delimitation = this.input.peek(); - if(STRING_LIMITORS.includes(delimitation)) { + if(STRING_LIMITERS.includes(delimitation)) { this.input.skip(delimitation) let included = ""; let justEscaped = false; - while(!this.input.atEnd() && (!STRING_LIMITORS.includes(this.input.peek()) || justEscaped)) { - justEscaped = this.input.peek() == "\\" + while(!this.input.atEnd() && (!STRING_LIMITERS.includes(this.input.peek()) || justEscaped)) { + justEscaped = this.input.peek() === "\\" if(!justEscaped) included += this.input.next(); } @@ -92,8 +97,8 @@ class ExpressionTokenizer { readNumber() { let included = ""; let hasDot = false; - while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() == '.')) { - if(this.input.peek() == ".") { + while(!this.input.atEnd() && (NUMBER_CHARS.includes(this.input.peek()) || this.input.peek() === '.')) { + if(this.input.peek() === ".") { if(hasDot) this.input.raise("Unexpected '.'. Expected digit") hasDot = true; } @@ -130,14 +135,14 @@ class ExpressionTokenizer { if(this.input.atEnd()) return null; let c = this.input.peek(); if(this.tokenizeWhitespaces && WHITESPACES.includes(c)) return this.readWhitespaces(); - if(STRING_LIMITORS.includes(c)) return this.readString(); + if(STRING_LIMITERS.includes(c)) return this.readString(); if(NUMBER_CHARS.includes(c)) return this.readNumber(); if(IDENTIFIER_CHARS.includes(c.toLowerCase())) return this.readIdentifier(); if(OPERATORS.includes(c)) return this.readOperator(); if(Reference.CONSTANTS_LIST.includes(c)) return new Token(TokenType.CONSTANT, this.input.next(), this.input.position-1); - if(PUNCTUTATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position-1); + if(PUNCTUATION.includes(c)) return new Token(TokenType.PUNCT, this.input.next(), this.input.position-1); if(this.errorOnUnknown) - this.input.throw("Unknown token character " + c) + this.input.raise("Unknown token character " + c) else return new Token(TokenType.UNKNOWN, this.input.next(), this.input.position-1); } @@ -163,7 +168,7 @@ class ExpressionTokenizer { skip(type) { let next = this.next(); - if(next.type != type) - input.raise("Unexpected token " + next.type.toLowerCase() + ' "' + next.value + '". Expected ' + type.toLowerCase()); + if(next.type !== type) + this.input.raise("Unexpected token " + next.type.toLowerCase() + ' "' + next.value + '". Expected ' + type.toLowerCase()); } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs new file mode 100644 index 0000000..0d859aa --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs @@ -0,0 +1,45 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * Base class for global APIs in runtime. + */ +export class RuntimeAPI { + + /** + * + * @param {string} name - Name of the API + * @param {(RuntimeAPI|undefined)[]} requires - List of APIs required to initialize this one. + */ + constructor(name, requires = []) { + console.log(`Loading module ${name}...`) + this.__check_requirements(requires, name) + } + + /** + * Checks if all requirements are defined. + * @param {(RuntimeAPI|undefined)[]} requires + * @param {string} name + */ + __check_requirements(requires, name) { + for(let requirement of requires) { + if(requirement === undefined) + throw new Error(`Requirement ${requires.indexOf(requirement)} of ${name} has not been initialized.`) + } + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs similarity index 75% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs index 0b62f8f..162e751 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/utils.mjs @@ -1,24 +1,22 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -.pragma library - -var powerpos = { +const powerpos = { "-": "⁻", "+": "⁺", "=": "⁼", @@ -62,12 +60,13 @@ var powerpos = { "z": "ᶻ" } -var exponents = [ +const exponents = [ "⁰","¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹" ] -var exponentReg = new RegExp('(['+exponents.join('')+']+)', 'g') -var indicepos = { +const exponentReg = new RegExp('(['+exponents.join('')+']+)', 'g') + +const indicepos = { "-": "₋", "+": "₊", "=": "₌", @@ -103,10 +102,10 @@ var indicepos = { "x": "ₓ", } // Put a text in sup position -function textsup(text) { - var ret = "" +export function textsup(text) { + let ret = "" text = text.toString() - for (var i = 0; i < text.length; i++) { + for (let i = 0; i < text.length; i++) { if(Object.keys(powerpos).indexOf(text[i]) >= 0) { ret += powerpos[text[i]] } else { @@ -117,10 +116,10 @@ function textsup(text) { } // Put a text in sub position -function textsub(text) { - var ret = "" +export function textsub(text) { + let ret = "" text = text.toString() - for (var i = 0; i < text.length; i++) { + for (let i = 0; i < text.length; i++) { if(Object.keys(indicepos).indexOf(text[i]) >= 0) { ret += indicepos[text[i]] } else { @@ -130,8 +129,13 @@ function textsub(text) { return ret } -function simplifyExpression(str) { - var replacements = [ +/** + * Simplifies (mathematically) a mathematical expression. + * @param {string} str - Expression to parse + * @returns {string} + */ +export function simplifyExpression(str) { + let replacements = [ // Operations not done by parser. // [// Decomposition way 2 // /(^|[+-] |\()([-.\d\w]+) ([*/]) \((([-.\d\w] [*/] )?[-\d\w.]+) ([+\-]) (([-.\d\w] [*/] )?[\d\w.+]+)\)($| [+-]|\))/g, @@ -149,16 +153,16 @@ function simplifyExpression(str) { // n1 & n3 are multiplied, opeM is the main operation (- or +). // Putting all n in form of number //n2 = n2 == undefined ? 1 : parseFloat(n) - n1 = m1 == undefined ? 1 : eval(m1 + '1') - n2 = m2 == undefined ? 1 : eval('1' + m2) - n3 = m3 == undefined ? 1 : eval(m3 + '1') - n4 = m4 == undefined ? 1 : eval('1' + m4) - //var [n1, n2, n3, n4] = [n1, n2, n3, n4].map(n => n == undefined ? 1 : parseFloat(n)) + n1 = m1 === undefined ? 1 : eval(m1 + '1') + n2 = m2 === undefined ? 1 : eval('1' + m2) + n3 = m3 === undefined ? 1 : eval(m3 + '1') + n4 = m4 === undefined ? 1 : eval('1' + m4) + //let [n1, n2, n3, n4] = [n1, n2, n3, n4].map(n => n == undefined ? 1 : parseFloat(n)) // Falling back to * in case it does not exist (the corresponding n would be 1) - var [ope2, ope4] = [ope2, ope4].map(ope => ope == '/' ? '/' : '*') - var coeff1 = n1*n2 - var coeff2 = n3*n4 - var coefficient = coeff1+coeff2-(opeM == '-' ? 2*coeff2 : 0) + [ope2, ope4] = [ope2, ope4].map(ope => ope === '/' ? '/' : '*') + let coeff1 = n1*n2 + let coeff2 = n3*n4 + let coefficient = coeff1+coeff2-(opeM === '-' ? 2*coeff2 : 0) return `${coefficient} * π` } @@ -172,14 +176,14 @@ function simplifyExpression(str) { function(match, b4, middle, after) {return `${b4}${middle}${after}`} ], [ // Removing parenthesis when content is only multiplied. - /(^|[*\/-+] |\()\(([^)(+-]+)\)($| [*\/]|\))/g, + /(^|[*\/+-] |\()\(([^)(+-]+)\)($| [*\/]|\))/g, function(match, b4, middle, after) {return `${b4}${middle}${after}`} ], - [// Simplification additions/substractions. - /(^|[^*\/] |\()([-.\d]+) (\+|\-) (\([^)(]+\)|[^)(]+) (\+|\-) ([-.\d]+)($| [^*\/]|\))/g, + [// Simplification additions/subtractions. + /(^|[^*\/] |\()([-.\d]+) [+-] (\([^)(]+\)|[^)(]+) [+-] ([-.\d]+)($| [^*\/]|\))/g, function(match, b4, n1, op1, middle, op2, n2, after) { - var total - if(op2 == '+') { + let total + if(op2 === '+') { total = parseFloat(n1) + parseFloat(n2) } else { total = parseFloat(n1) - parseFloat(n2) @@ -188,14 +192,14 @@ function simplifyExpression(str) { } ], [// Simplification multiplications/divisions. - /([-.\d]+) (\*|\/) (\([^)(]+\)|[^)(+-]+) (\*|\/) ([-.\d]+)/g, + /([-.\d]+) [*\/] (\([^)(]+\)|[^)(+-]+) [*\/] ([-.\d]+)/g, function(match, n1, op1, middle, op2, n2) { - if(parseInt(n1) == n1 && parseInt(n2) == n2 && op2 == '/' && - (parseInt(n1) / parseInt(n2)) % 1 != 0) { + if(parseInt(n1) === n1 && parseInt(n2) === n2 && op2 === '/' && + (parseInt(n1) / parseInt(n2)) % 1 !== 0) { // Non int result for int division. return `(${n1} / ${n2}) ${op1} ${middle}` } else { - if(op2 == '*') { + if(op2 === '*') { return `${parseFloat(n1) * parseFloat(n2)} ${op1} ${middle}` } else { return `${parseFloat(n1) / parseFloat(n2)} ${op1} ${middle}` @@ -206,7 +210,7 @@ function simplifyExpression(str) { [// Starting & ending parenthesis if not needed. /^\s*\((.*)\)\s*$/g, function(match, middle) { - var str = middle + let str = middle // Replace all groups while(/\([^)(]+\)/g.test(str)) str = str.replace(/\([^)(]+\)/g, '') @@ -225,19 +229,19 @@ function simplifyExpression(str) { // [/(\s|^|\()0(\.0+)? \* ([^)(+-]+)/g, '$10'], // [/(\([^)(]\)) \* 0(\.0+)?(\s|$|\))/g, '0$3'], // [/([^)(+-]) \* 0(\.0+)?(\s|$|\))/g, '0$3'], - // [/(\s|^|\()1(\.0+)? (\*|\/) /g, '$1'], + // [/(\s|^|\()1(\.0+)? [\*\/] /g, '$1'], // [/(\s|^|\()0(\.0+)? (\+|\-) /g, '$1'], - // [/ (\*|\/) 1(\.0+)?(\s|$|\))/g, '$3'], + // [/ [\*\/] 1(\.0+)?(\s|$|\))/g, '$3'], // [/ (\+|\-) 0(\.0+)?(\s|$|\))/g, '$3'], // [/(^| |\() /g, '$1'], // [/ ($|\))/g, '$1'], ] // Replacements - var found + let found do { found = false - for(var replacement of replacements) + for(let replacement of replacements) while(replacement[0].test(str)) { found = true str = str.replace(replacement[0], replacement[1]) @@ -247,9 +251,15 @@ function simplifyExpression(str) { } -function makeExpressionReadable(str) { - var replacements = [ - // variables +/** + * Transforms a mathematical expression to make it readable by humans. + * NOTE: Will break parsing of expression. + * @param {string} str - Expression to parse. + * @returns {string} + */ +export function makeExpressionReadable(str) { + let replacements = [ + // letiables [/pi/g, 'π'], [/Infinity/g, '∞'], [/inf/g, '∞'], @@ -264,28 +274,35 @@ function makeExpressionReadable(str) { [/(\d|\))×/g, '$1'], //[/×(\d|\()/g, '$1'], [/([^a-z])\(([^)(+.\/-]+)\)/g, "$1×$2"], - [/integral\((.+),\s?(.+),\s?("|')(.+)("|'),\s?("|')(.+)("|')\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { + [/integral\((.+),\s?(.+),\s?["'](.+)["'],\s?["'](.+)["']\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { if(a.length < b.length) { return `∫${textsub(a)}${textsup(b)} ${body} d${by}` } else { return `∫${textsup(b)}${textsub(a)} ${body} d${by}` } }], - [/derivative\(?("|')(.+)("|'), ?("|')(.+)("|'), ?(.+)\)?/g, function(match, p1, body, p2, p3, by, p4, x) { + [/derivative\(?["'](.+)["'], ?["'](.+)["'], ?(.+)\)?/g, function(match, p1, body, p2, p3, by, p4, x) { return `d(${body.replace(new RegExp(by, 'g'), 'x')})/dx` }] ] // str = simplifyExpression(str) // Replacements - for(var replacement of replacements) + for(let replacement of replacements) while(replacement[0].test(str)) str = str.replace(replacement[0], replacement[1]) return str } -function parseName(str, removeUnallowed = true) { - var replacements = [ +/** + * Parses a variable name to make it readable by humans. + * + * @param {string} str - Variable name to parse + * @param {boolean} removeUnallowed - Remove domain symbols disallowed in name. + * @returns {string} - The parsed name + */ +export function parseName(str, removeUnallowed = true) { + let replacements = [ // Greek letters [/([^a-z]|^)al(pha)?([^a-z]|$)/g, '$1α$3'], [/([^a-z]|^)be(ta)?([^a-z]|$)/g, '$1β$3'], @@ -330,7 +347,7 @@ function parseName(str, removeUnallowed = true) { ] if(!removeUnallowed) replacements.pop() // Replacements - for(var replacement of replacements) + for(let replacement of replacements) str = str.replace(replacement[0], replacement[1]) return str } @@ -339,21 +356,36 @@ String.prototype.toLatinUppercase = function() { return this.replace(/[a-z]/g, function(match){return match.toUpperCase()}) } -function camelCase2readable(label) { - var parsed = parseName(label, false) +/** + * Transforms camel case strings to a space separated one. + * + * @param {string} label - Camel case to parse + * @returns {string} Parsed label. + */ +export function camelCase2readable(label) { + let parsed = parseName(label, false) return parsed.charAt(0).toLatinUppercase() + parsed.slice(1).replace(/([A-Z])/g," $1") } -function getRandomColor() { - var clrs = '0123456789ABCDEF'; - var color = '#'; - for(var i = 0; i < 6; i++) { - color += clrs[Math.floor(Math.random() * (16-5*(i%2==0)))]; +/** + * Creates a randomized color string. + * @returns {string} + */ +export function getRandomColor() { + let clrs = '0123456789ABCDEF'; + let color = '#'; + for(let i = 0; i < 6; i++) { + color += clrs[Math.floor(Math.random() * (16-5*(i%2===0)))]; } return color; } -function escapeHTML(str) { +/** + * Escapes text to html entities. + * @param {string} str + * @returns {string} + */ +export function escapeHTML(str) { return str.replace(/&/g,'&').replace(//g,'>') ; } @@ -364,6 +396,6 @@ function escapeHTML(str) { * @param {string} expression - The expression to replace in. * @return {string} The parsed expression */ -function exponentsToExpression(expression) { +export function exponentsToExpression(expression) { return expression.replace(exponentReg, (m, exp) => '^' + exp.split('').map((x) => exponents.indexOf(x)).join('')) } From 861bb001c98c134cf4729bd986a9848266584f46 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Thu, 28 Mar 2024 22:52:14 +0100 Subject: [PATCH 183/436] Changing version, making Helper objects globals, adding their polyfills. --- LogarithmPlotter/__init__.py | 4 +- LogarithmPlotter/logarithmplotter.py | 9 +- .../LogarithmPlotter/LogarithmPlotter.qml | 11 +-- .../LogarithmPlotter/js/history/common.mjs | 2 +- .../LogarithmPlotter/js/lib/qmlpolyfills.mjs | 27 +++++- .../ad5001/LogarithmPlotter/js/math/latex.mjs | 7 +- LogarithmPlotter/util/latex.py | 88 ++++++++----------- 7 files changed, 77 insertions(+), 71 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index 4b060a5..d8bb713 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,8 +17,8 @@ """ from shutil import which -__VERSION__ = "0.5.0" -is_release = True +__VERSION__ = "0.5.1" +is_release = False # Check if development version, if so get the date of the latest git patch diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 28affed..f8670bd 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -112,9 +112,12 @@ def run(): global tmpfile helper = Helper(pwd, tmpfile) latex = Latex(tempdir) - engine.globalObject().setProperty('Runtime', engine.newObject()) - engine.rootContext().setContextProperty("Helper", helper) - engine.rootContext().setContextProperty("Latex", latex) + modules = engine.newObject() + engine.globalObject().setProperty('Runtime', modules) + engine.globalObject().setProperty('Helper', engine.newQObject(helper)) + engine.globalObject().setProperty("Latex", engine.newQObject(latex)) + # engine.rootContext().setContextProperty("Helper", helper) + # engine.rootContext().setContextProperty("Latex", latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 1715967..4c9a7b4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -44,16 +44,7 @@ ApplicationWindow { color: sysPalette.window title: "LogarithmPlotter " + (settings.saveFilename != "" ? " - " + settings.saveFilename.split('/').pop() : "") + (history.saved ? "" : "*") - SystemPalette { - id: sysPalette; colorGroup: SystemPalette.Active - - Component.onCompleted: { - // LatexJS initialization. - Runtime.Latex.enabled = Helper.getSettingBool("enable_latex") - Runtime.Latex.Renderer = Latex - Runtime.Latex.defaultColor = sysPalette.windowText - } - } + SystemPalette { id: sysPalette; colorGroup: SystemPalette.Active } SystemPalette { id: sysPaletteIn; colorGroup: SystemPalette.Disabled } menuBar: appMenu.trueItem diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index d9a3bc8..78476ca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -108,7 +108,7 @@ export class Action { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") let imgDepth = Runtime.History.imageDepth - let [src, width, height] = Latex.Renderer.render( + let [src, width, height] = Latex.render( latexString, imgDepth * (Runtime.History.fontSize + 2), Runtime.History.themeTextColor diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index d3214f7..a940967 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -27,4 +27,29 @@ qsTr = qsTr || function(string) { throw new Error('qsTr not implemented.'); } /** @type {function(string, string): string} */ QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); } /** @type {function(string|boolean|int): string} */ -String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } \ No newline at end of file +String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } + +/** Typehints for Helper. */ +const Helper = { + /** @type {function(string): boolean} */ + getSettingBool: (setting) => true, + /** @type {function(string): int} */ + getSettingInt: (setting) => 0, + /** @type {function(string): string} */ + getSetting: (setting) => '', + /** @type {function(string, boolean)} */ + setSettingBool: (setting, value) => {}, + /** @type {function(string, int)} */ + setSettingInt: (setting, value) => 0, + /** @type {function(string, string)} */ + setSetting: (setting, value) => '', + /** @type {function(string, string)} */ + write: (filename, data) => {}, + /** @type {function(string): string} */ + load: (filename) => '', +} + +const Latex = { + /** @type {function(string, number, string): string} */ + render: (latex_markup, font_size, color) => '', +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs index c7975e7..ef1f862 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs @@ -50,11 +50,12 @@ class LatexAPI extends RuntimeAPI { /** * true if latex has been enabled by the user, false otherwise. */ - this.enabled = false + this.enabled = Helper.getSettingBool("enable_latex") /** - * LaTeX python backend QObject. + * Mirror method for Python object. + * @type {function(string, number, string): string}. */ - this.Renderer = null + this.render = Latex.render } /** diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index ce22bb7..d519e18 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -51,17 +51,19 @@ $$$$ $markup $$$$ \end{document} """) - + + class Latex(QObject): """ Base class to convert Latex equations into PNG images with custom font color and size. It doesn't have any python dependency, but requires a working latex installation and dvipng to be installed on the system. """ + def __init__(self, tempdir: TemporaryDirectory): QObject.__init__(self) self.tempdir = tempdir - + def check_latex_install(self): """ Checks if the current latex installation is valid. @@ -69,22 +71,23 @@ class Latex(QObject): if LATEX_PATH is None: print("No Latex installation found.") if "--test-build" not in argv: - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", + QCoreApplication.translate("latex", "No Latex installation found.\nIf you already have a latex distribution installed, make sure it's installed on your path.\nOtherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/.")) elif DVIPNG_PATH is None: print("DVIPNG not found.") if "--test-build" not in argv: - QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) - + QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "DVIPNG was not found. Make sure you include it from your Latex distribution.")) + @Property(bool) def latexSupported(self): return LATEX_PATH is not None and DVIPNG_PATH is not None - + @Slot(str, float, QColor, result=str) def render(self, latex_markup: str, font_size: float, color: QColor) -> str: """ Prepares and renders a latex string into a png file. """ - markup_hash = "render"+str(hash(latex_markup)) + markup_hash = "render" + str(hash(latex_markup)) export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}') if self.latexSupported and not path.exists(export_path + ".png"): print("Rendering", latex_markup, export_path) @@ -101,21 +104,21 @@ class Latex(QObject): # self.convert_dvi_to_png(latex_path, export_path+"@2", font_size*2, color) # self.convert_dvi_to_png(latex_path, export_path+"@3", font_size*3, color) # self.convert_dvi_to_png(latex_path, export_path+"@4", font_size*4, color) - except Exception as e: # One of the processes failed. A message will be sent every time. + except Exception as e: # One of the processes failed. A message will be sent every time. raise e - img = QImage(export_path); + img = QImage(export_path) # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded return f'{export_path}.png,{img.width()},{img.height()}' - + def create_latex_doc(self, export_path: str, latex_markup: str): """ Creates a temporary latex document with base file_hash as file name and a given expression markup latex_markup. """ ltx_path = export_path + ".tex" f = open(export_path + ".tex", 'w') - f.write(DEFAULT_LATEX_DOC.substitute(markup = latex_markup)) + f.write(DEFAULT_LATEX_DOC.substitute(markup=latex_markup)) f.close() - + def convert_latex_to_dvi(self, export_path: str): """ Converts a TEX file to a DVI file. @@ -124,7 +127,7 @@ class Latex(QObject): LATEX_PATH, export_path + ".tex" ]) - + def convert_dvi_to_png(self, dvi_path: str, export_path: str, font_size: float, color: QColor): """ Converts a DVI file to a PNG file. @@ -135,61 +138,44 @@ class Latex(QObject): depth = int(font_size * 72.27 / 100) * 10 self.run([ DVIPNG_PATH, - '-T', 'tight', # Make sure image borders are as tight around the equation as possible to avoid blank space. - '--truecolor', # Make sure it's rendered in 24 bit colors. - '-D',f'{depth}', # Depth of the image - '-bg', 'Transparent', # Transparent background - '-fg',f'{fg}', # Foreground of the wanted color. - f'{dvi_path}.dvi', # Input file - '-o',f'{export_path}.png', # Output file + '-T', 'tight', # Make sure image borders are as tight around the equation as possible to avoid blank space. + '--truecolor', # Make sure it's rendered in 24 bit colors. + '-D', f'{depth}', # Depth of the image + '-bg', 'Transparent', # Transparent background + '-fg', f'{fg}', # Foreground of the wanted color. + f'{dvi_path}.dvi', # Input file + '-o', f'{export_path}.png', # Output file ]) - + def run(self, process: list): """ Runs a subprocess and handles exceptions and messages them to the user. """ proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir.name) try: - out, err = proc.communicate(timeout=2) # 2 seconds is already FAR too long. + out, err = proc.communicate(timeout=2) # 2 seconds is already FAR too long. if proc.returncode != 0: # Process errored - QMessageBox.warning(None, "LogarithmPlotter - Latex", - QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), proc.returncode, str(out, 'utf8')+"\n"+str(err,'utf8'))) - raise Exception(" ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) + QMessageBox.warning(None, "LogarithmPlotter - Latex", + QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") + .format(" ".join(process), proc.returncode, + str(out, 'utf8') + "\n" + str(err, 'utf8'))) + raise Exception( + " ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, + 'utf8') + "\n" + str( + err, 'utf8')) except TimeoutExpired as e: # Process timed out proc.kill() out, err = proc.communicate() QMessageBox.warning(None, "LogarithmPlotter - Latex", QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' took too long to finish:\n{}\nPlease make sure your latex installation is correct and report a bug if so.") - .format(" ".join(process), str(out, 'utf8')+"\n"+str(err,'utf8'))) - raise Exception(" ".join(process) + " process timed out:\n" + str(out, 'utf8')+"\n"+str(err,'utf8')) - - def cleanup(self, export_path): + .format(" ".join(process), str(out, 'utf8') + "\n" + str(err, 'utf8'))) + raise Exception(" ".join(process) + " process timed out:\n" + str(out, 'utf8') + "\n" + str(err, 'utf8')) + + def cleanup(self, export_path): """ Removes auxiliary, logs and Tex temporary files. """ for i in [".tex", ".aux", ".log"]: remove(export_path + i) - - """ - @Slot(str, float, QColor, result=str) - def render_legacy(self, latexstring, font_size, color = True): - exprpath = path.join(self.tempdir.name, f'{hash(latexstring)}_{font_size}_{color.rgb()}.png') - print("Rendering", latexstring, exprpath) - if not path.exists(exprpath): - fg = color.convertTo(QColor.Rgb) - fg = f'rgb {fg.redF()} {fg.greenF()} {fg.blueF()}' - preview('$${' + latexstring + '}$$', viewer='file', filename=exprpath, dvioptions=[ - "-T", "tight", - "-z", "0", - "--truecolor", - f"-D {int(font_size * 72.27 / 100) * 10}", # See https://linux.die.net/man/1/dvipng#-D for convertion - "-bg", "Transparent", - "-fg", fg], - euler=False) - img = QImage(exprpath); - # Small hack, not very optimized since we load the image twice, but you can't pass a QImage to QML and expect it to be loaded - return f'{exprpath},{img.width()},{img.height()}' - """ From 73cba855921276d5e0f452e0f2a1b0102f2a3c95 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 29 Mar 2024 01:55:13 +0100 Subject: [PATCH 184/436] Creating Canvas JS Module. --- LogarithmPlotter/logarithmplotter.py | 2 +- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 10 +- .../LogarithmPlotter/History/History.qml | 6 +- .../LogarithmPlotter/LogGraphCanvas.qml | 331 +---------- .../LogarithmPlotter/LogarithmPlotter.qml | 26 +- .../ObjectLists/Editor/CustomPropertyList.qml | 19 +- .../ObjectLists/Editor/Dialog.qml | 12 +- .../ObjectLists/ObjectCreationGrid.qml | 10 +- .../ObjectLists/ObjectLists.qml | 20 +- .../ObjectLists/ObjectRow.qml | 12 +- .../LogarithmPlotter/PickLocationOverlay.qml | 19 +- .../Setting/ExpressionEditor.qml | 16 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 8 +- .../ViewPositionChangeOverlay.qml | 5 +- .../js/{modules.js => autoload.js} | 1 + .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 523 ++++++++++++++++++ .../LogarithmPlotter/js/history/common.mjs | 22 +- .../js/lib/expr-eval/integration.js | 10 +- .../LogarithmPlotter/js/lib/qmlpolyfills.mjs | 15 +- .../LogarithmPlotter/js/math/expression.mjs | 20 +- .../ad5001/LogarithmPlotter/js/math/latex.mjs | 41 +- .../LogarithmPlotter/js/math/sequence.mjs | 10 +- .../js/{runtime.mjs => modules.mjs} | 6 +- .../eu/ad5001/LogarithmPlotter/js/objects.mjs | 8 +- .../LogarithmPlotter/js/objs/autoload.mjs | 2 +- .../LogarithmPlotter/js/objs/common.mjs | 43 +- .../LogarithmPlotter/js/objs/function.mjs | 26 +- .../LogarithmPlotter/js/objs/gainbode.mjs | 27 +- .../LogarithmPlotter/js/objs/phasebode.mjs | 11 +- .../ad5001/LogarithmPlotter/js/objs/point.mjs | 20 +- .../LogarithmPlotter/js/objs/repartition.mjs | 42 +- .../LogarithmPlotter/js/objs/sequence.mjs | 6 +- .../js/objs/sommegainsbode.mjs | 10 +- .../js/objs/sommephasesbode.mjs | 10 +- .../ad5001/LogarithmPlotter/js/objs/text.mjs | 4 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 34 +- 36 files changed, 797 insertions(+), 590 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{modules.js => autoload.js} (87%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{runtime.mjs => modules.mjs} (89%) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index f8670bd..5270534 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -113,7 +113,7 @@ def run(): helper = Helper(pwd, tmpfile) latex = Latex(tempdir) modules = engine.newObject() - engine.globalObject().setProperty('Runtime', modules) + engine.globalObject().setProperty('Modules', modules) engine.globalObject().setProperty('Helper', engine.newQObject(helper)) engine.globalObject().setProperty("Latex", engine.newQObject(latex)) # engine.rootContext().setContextProperty("Helper", helper) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index a77de0c..3de96ca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -103,17 +103,17 @@ MenuBar { title: qsTr("&Create") // Services repeater Repeater { - model: Object.keys(Runtime.Objects.types) + model: Object.keys(Modules.Objects.types) MenuItem { - text: Runtime.Objects.types[modelData].displayType() - visible: Runtime.Objects.types[modelData].createable() + text: Modules.Objects.types[modelData].displayType() + visible: Modules.Objects.types[modelData].createable() height: visible ? implicitHeight : 0 icon.name: modelData icon.source: './icons/objects/' + modelData + '.svg' icon.color: sysPalette.buttonText onTriggered: { - var newObj = Runtime.Objects.createNewRegisteredObject(modelData) + var newObj = Modules.Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() } @@ -151,7 +151,7 @@ MenuBar { checked: Helper.getSettingBool("enable_latex") onTriggered: { Helper.setSettingBool("enable_latex", checked) - Runtime.Latex.enabled = checked + Modules.Latex.enabled = checked drawCanvas.requestPaint() } icon.name: 'Expression' diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml index 8a9a6ba..afc7281 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/History/History.qml @@ -212,8 +212,8 @@ Item { } Component.onCompleted: { - Runtime.History.history = historyObj - Runtime.History.themeTextColor = sysPalette.windowText - Runtime.History.imageDepth = Screen.devicePixelRatio + Modules.History.history = historyObj + Modules.History.themeTextColor = sysPalette.windowText + Modules.History.imageDepth = Screen.devicePixelRatio } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 908bdb6..973142f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -126,37 +126,6 @@ Canvas { */ property int maxgradx: 20 - /*! - \qmlproperty var LogGraphCanvas::yaxisstepExpr - Expression for the y axis step (used to create labels). - */ - property var yaxisstepExpr: (new MathLib.Expression(`x*(${yaxisstep})`)) - /*! - \qmlproperty double LogGraphCanvas::yaxisstep1 - Value of the for the y axis step. - */ - property double yaxisstep1: yaxisstepExpr.execute(1) - /*! - \qmlproperty int LogGraphCanvas::drawMaxY - Minimum value of y that should be drawn onto the canvas. - */ - property int drawMaxY: Math.ceil(Math.max(Math.abs(ymax), Math.abs(px2y(canvasSize.height)))/yaxisstep1) - /*! - \qmlproperty var LogGraphCanvas::xaxisstepExpr - Expression for the x axis step (used to create labels). - */ - property var xaxisstepExpr: (new MathLib.Expression(`x*(${xaxisstep})`)) - /*! - \qmlproperty double LogGraphCanvas::xaxisstep1 - Value of the for the x axis step. - */ - property double xaxisstep1: xaxisstepExpr.execute(1) - /*! - \qmlproperty int LogGraphCanvas::drawMaxX - Maximum value of x that should be drawn onto the canvas. - */ - property int drawMaxX: Math.ceil(Math.max(Math.abs(xmin), Math.abs(px2x(canvasSize.width)))/xaxisstep1) - /*! \qmlproperty var LogGraphCanvas::imageLoaders Dictionary of format {image: [callback.image data]} containing data for defered image loading. @@ -168,7 +137,10 @@ Canvas { */ property var ctx - Component.onCompleted: imageLoaders = {} + Component.onCompleted: { + imageLoaders = {} + Modules.Canvas.initialize(canvas, drawingErrorDialog) + } Native.MessageDialog { id: drawingErrorDialog @@ -183,27 +155,7 @@ Canvas { onPaint: function(rect) { //console.log('Redrawing') if(rect.width == canvas.width) { // Redraw full canvas - ctx = getContext("2d"); - reset(ctx) - drawGrille(ctx) - drawAxises(ctx) - drawLabels(ctx) - ctx.lineWidth = linewidth - for(var objType in Runtime.Objects.currentObjects) { - for(var obj of Runtime.Objects.currentObjects[objType]){ - ctx.strokeStyle = obj.color - ctx.fillStyle = obj.color - if(obj.visible) - try { - obj.draw(canvas, ctx) - } catch(e) { - // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) - drawingErrorDialog.showDialog(objType, obj.name, e.message) - history.undo() - } - } - } - ctx.lineWidth = 1 + Modules.Canvas.redraw() } } @@ -216,277 +168,4 @@ Canvas { } }) } - - /*! - \qmlmethod void LogGraphCanvas::reset(var ctx) - Resets the canvas to a blank one with default setting using 2D \c ctx. - */ - function reset(ctx){ - // Reset - ctx.fillStyle = "#FFFFFF" - ctx.strokeStyle = "#000000" - ctx.font = `${canvas.textsize}px sans-serif` - ctx.fillRect(0,0,width,height) - } - - // Drawing the log based graph - - /*! - \qmlmethod void LogGraphCanvas::drawGrille(var ctx) - Draws the grid using 2D \c ctx. - */ - function drawGrille(ctx) { - ctx.strokeStyle = "#C0C0C0" - if(logscalex) { - for(var xpow = -maxgradx; xpow <= maxgradx; xpow++) { - for(var xmulti = 1; xmulti < 10; xmulti++) { - drawXLine(ctx, Math.pow(10, xpow)*xmulti) - } - } - } else { - for(var x = 0; x < drawMaxX; x+=1) { - drawXLine(ctx, x*xaxisstep1) - drawXLine(ctx, -x*xaxisstep1) - } - } - for(var y = 0; y < drawMaxY; y+=1) { - drawYLine(ctx, y*yaxisstep1) - drawYLine(ctx, -y*yaxisstep1) - } - } - - /*! - \qmlmethod void LogGraphCanvas::drawAxises(var ctx) - Draws the graph axises using 2D \c ctx. - */ - function drawAxises(ctx) { - ctx.strokeStyle = "#000000" - var axisypos = logscalex ? 1 : 0 - drawXLine(ctx, axisypos) - drawYLine(ctx, 0) - var axisypx = x2px(axisypos) // X coordinate of Y axis - var axisxpx = y2px(0) // Y coordinate of X axis - // Drawing arrows - drawLine(ctx, axisypx, 0, axisypx-10, 10) - drawLine(ctx, axisypx, 0, axisypx+10, 10) - drawLine(ctx, canvasSize.width, axisxpx, canvasSize.width-10, axisxpx-10) - drawLine(ctx, canvasSize.width, axisxpx, canvasSize.width-10, axisxpx+10) - } - - /*! - \qmlmethod void LogGraphCanvas::drawLabels(var ctx) - Draws all labels (graduation & axises labels) using 2D \c ctx. - */ - function drawLabels(ctx) { - var axisypx = x2px(logscalex ? 1 : 0) // X coordinate of Y axis - var axisxpx = y2px(0) // Y coordinate of X axis - // Labels - ctx.fillStyle = "#000000" - ctx.font = `${canvas.textsize}px sans-serif` - ctx.fillText(ylabel, axisypx+10, 24) - var textSize = ctx.measureText(xlabel).width - ctx.fillText(xlabel, canvasSize.width-14-textSize, axisxpx-5) - // Axis graduation labels - ctx.font = `${canvas.textsize-4}px sans-serif` - - var txtMinus = ctx.measureText('-').width - if(showxgrad) { - if(logscalex) { - for(var xpow = -maxgradx; xpow <= maxgradx; xpow+=1) { - var textSize = ctx.measureText("10"+Utils.textsup(xpow)).width - if(xpow != 0) - drawVisibleText(ctx, "10"+Utils.textsup(xpow), x2px(Math.pow(10,xpow))-textSize/2, axisxpx+16+(6*(xpow==1))) - } - } else { - for(var x = 1; x < drawMaxX; x += 1) { - var drawX = x*xaxisstep1 - var txtX = xaxisstepExpr.simplify(x).replace(/^\((.+)\)$/, '$1') - var textSize = measureText(ctx, txtX, 6).height - drawVisibleText(ctx, txtX, x2px(drawX)-4, axisxpx+textsize/2+textSize) - drawVisibleText(ctx, '-'+txtX, x2px(-drawX)-4, axisxpx+textsize/2+textSize) - } - } - } - if(showygrad) { - for(var y = 0; y < drawMaxY; y += 1) { - var drawY = y*yaxisstep1 - var txtY = yaxisstepExpr.simplify(y).replace(/^\((.+)\)$/, '$1') - var textSize = ctx.measureText(txtY).width - drawVisibleText(ctx, txtY, axisypx-6-textSize, y2px(drawY)+4+(10*(y==0))) - if(y != 0) - drawVisibleText(ctx, '-'+txtY, axisypx-6-textSize-txtMinus, y2px(-drawY)+4) - } - } - ctx.fillStyle = "#FFFFFF" - } - - /*! - \qmlmethod void LogGraphCanvas::drawXLine(var ctx, double x) - Draws an horizontal line at \c x plot coordinate using 2D \c ctx. - */ - function drawXLine(ctx, x) { - if(isVisible(x, ymax)) { - drawLine(ctx, x2px(x), 0, x2px(x), canvasSize.height) - } - } - - /*! - \qmlmethod void LogGraphCanvas::drawXLine(var ctx, double x) - Draws an vertical line at \c y plot coordinate using 2D \c ctx. - */ - function drawYLine(ctx, y) { - if(isVisible(xmin, y)) { - drawLine(ctx, 0, y2px(y), canvasSize.width, y2px(y)) - } - } - - /*! - \qmlmethod void LogGraphCanvas::drawVisibleText(var ctx, string text, double x, double y) - Writes multline \c text onto the canvas using 2D \c ctx. - \note The \c x and \c y properties here are relative to the canvas, not the plot. - */ - function drawVisibleText(ctx, text, x, y) { - if(x > 0 && x < canvasSize.width && y > 0 && y < canvasSize.height) { - text.toString().split("\n").forEach(function(txt, i){ - ctx.fillText(txt, x, y+(canvas.textsize*i)) - }) - } - } - - /*! - \qmlmethod void LogGraphCanvas::drawVisibleImage(var ctx, var image, double x, double y) - Draws an \c image onto the canvas using 2D \c ctx. - \note The \c x, \c y \c width and \c height properties here are relative to the canvas, not the plot. - */ - function drawVisibleImage(ctx, image, x, y, width, height) { - //console.log("Drawing image", isImageLoaded(image), isImageError(image)) - markDirty(Qt.rect(x, y, width, height)); - ctx.drawImage(image, x, y, width, height) - /*if(true || (x > 0 && x < canvasSize.width && y > 0 && y < canvasSize.height)) { - }*/ - } - - /*! - \qmlmethod var LogGraphCanvas::measureText(var ctx, string text) - Measures the wicth and height of a multiline \c text that would be drawn onto the canvas using 2D \c ctx. - Return format: dictionary {"width": width, "height": height} - */ - function measureText(ctx, text) { - let theight = 0 - let twidth = 0 - let defaultHeight = ctx.measureText("M").width // Approximate but good enough! - text.split("\n").forEach(function(txt, i){ - theight += defaultHeight - if(ctx.measureText(txt).width > twidth) twidth = ctx.measureText(txt).width - }) - return {'width': twidth, 'height': theight} - } - - /*! - \qmlmethod double LogGraphCanvas::x2px(double x) - Converts an \c x coordinate to it's relative position on the canvas. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function x2px(x) { - if(logscalex) { - var logxmin = Math.log(xmin) - return (Math.log(x)-logxmin)*xzoom - } else return (x - xmin)*xzoom - } - - /*! - \qmlmethod double LogGraphCanvas::y2px(double y) - Converts an \c y coordinate to it's relative position on the canvas. - The y axis not supporting logarithmic scale, it only support linear convertion. - */ - function y2px(y) { - return (ymax-y)*yzoom - } - - /*! - \qmlmethod double LogGraphCanvas::px2x(double px) - Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function px2x(px) { - if(logscalex) { - return Math.exp(px/xzoom+Math.log(xmin)) - } else return (px/xzoom+xmin) - } - - /*! - \qmlmethod double LogGraphCanvas::px2x(double px) - Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. - It supports both logarithmic and non logarithmic scale depending on the currently selected mode. - */ - function px2y(px) { - return -(px/yzoom-ymax) - } - - /*! - \qmlmethod bool LogGraphCanvas::isVisible(double x, double y) - Checks whether a plot point (\c x, \c y) is visible or not on the canvas. - */ - function isVisible(x, y) { - return (x2px(x) >= 0 && x2px(x) <= canvasSize.width) && (y2px(y) >= 0 && y2px(y) <= canvasSize.height) - } - - /*! - \qmlmethod bool LogGraphCanvas::drawLine(var ctx, double x1, double y1, double x2, double y2) - Draws a line from plot point (\c x1, \c y1) to plot point (\c x2, \¢ y2) using 2D \c ctx. - */ - function drawLine(ctx, x1, y1, x2, y2) { - ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.stroke(); - } - - /*! - \qmlmethod bool LogGraphCanvas::drawDashedLine2(var ctx, double x1, double y1, double x2, double y2) - Draws a dashed line from plot point (\c x1, \c y1) to plot point (\c x2, \¢ y2) using 2D \c ctx. - */ - function drawDashedLine2(ctx, x1, y1, x2, y2, dashPxSize = 5) { - ctx.setLineDash([dashPxSize, dashPxSize]); - drawLine(ctx, x1, y1, x2, y2) - ctx.setLineDash([]); - } - - /*! - \qmlmethod bool LogGraphCanvas::drawDashedLine(var ctx, double x1, double y1, double x2, double y2) - Draws a dashed line from plot point (\c x1, \c y1) to plot point (\c x2, \¢ y2) using 2D \c ctx. - (Legacy slower method) - */ - function drawDashedLine(ctx, x1, y1, x2, y2, dashPxSize = 10) { - var distance = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) - var progPerc = dashPxSize/distance - ctx.beginPath(); - ctx.moveTo(x1, y1); - for(var i = 0; i < 1; i += progPerc) { - ctx.lineTo(x1-(x1-x2)*i, y1-(y1-y2)*i) - ctx.moveTo(x1-(x1-x2)*(i+progPerc/2), y1-(y1-y2)*(i+progPerc/2)) - } - ctx.stroke(); - } - - /*! - \qmlmethod var LogGraphCanvas::renderLatexImage(string ltxText, color) - Renders latex markup \c ltxText to an image and loads it. Returns a dictionary with three values: source, width and height. - */ - function renderLatexImage(ltxText, color, callback) { - let [ltxSrc, ltxWidth, ltxHeight] = Latex.render(ltxText, textsize, color).split(",") - let imgData = { - "source": ltxSrc, - "width": parseFloat(ltxWidth), - "height": parseFloat(ltxHeight) - }; - if(!isImageLoaded(ltxSrc) && !isImageLoading(ltxSrc)){ - // Wait until the image is loaded to callback. - loadImage(ltxSrc) - imageLoaders[ltxSrc] = [callback, imgData] - } else { - // Callback directly - callback(canvas, ctx, imgData) - } - } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 4c9a7b4..3fb9697 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -23,7 +23,7 @@ import QtQuick.Layouts 1.12 import QtQuick // Auto loading all modules. -import "js/modules.js" as Modules +import "js/autoload.js" as ModulesAutoload import eu.ad5001.LogarithmPlotter.History 1.0 import eu.ad5001.LogarithmPlotter.ObjectLists 1.0 @@ -191,9 +191,9 @@ ApplicationWindow { filename += '.lpf' settings.saveFilename = filename var objs = {} - for(var objType in Runtime.Objects.currentObjects){ + for(var objType in Modules.Objects.currentObjects){ objs[objType] = [] - for(var obj of Runtime.Objects.currentObjects[objType]) { + for(var obj of Modules.Objects.currentObjects[objType]) { objs[objType].push(obj.export()) } } @@ -255,19 +255,19 @@ ApplicationWindow { root.width = data["width"] // Importing objects - Runtime.Objects.currentObjects = {} - Runtime.Object.keys(Objects.currentObjectsByName).forEach(key => { - delete Runtime.Objects.currentObjectsByName[key]; + Modules.Objects.currentObjects = {} + Modules.Object.keys(Objects.currentObjectsByName).forEach(key => { + delete Modules.Objects.currentObjectsByName[key]; // Required to keep the same reference for the copy of the object used in expression variable detection. // Another way would be to change the reference as well, but I feel like the code would be less clean. }) for(let objType in data['objects']) { - if(Object.keys(Runtime.Objects.types).indexOf(objType) > -1) { - Runtime.Objects.currentObjects[objType] = [] + if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { + Modules.Objects.currentObjects[objType] = [] for(let objData of data['objects'][objType]) { - let obj = new Runtime.Objects.types[objType](...objData) - Runtime.Objects.currentObjects[objType].push(obj) - Runtime.Objects.currentObjectsByName[obj.name] = obj + let obj = new Modules.Objects.types[objType](...objData) + Modules.Objects.currentObjects[objType].push(obj) + Modules.Objects.currentObjectsByName[obj.name] = obj } } else { error += qsTr("Unknown object type: %1.").arg(objType) + "\n"; @@ -275,8 +275,8 @@ ApplicationWindow { } // Updating object dependencies. - for(let objName in Runtime.Objects.currentObjectsByName) - Runtime.Objects.currentObjectsByName[objName].update() + for(let objName in Modules.Objects.currentObjectsByName) + Modules.Objects.currentObjectsByName[objName].update() // Importing history if("history" in data) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index eb163f3..a6f57d6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -130,6 +130,7 @@ Repeater { } } catch(e) { // Error in expression or domain + console.trace() parsingErrorDialog.showDialog(propertyName, newValue, e.message) } } @@ -187,8 +188,8 @@ Repeater { // Base, untranslated version of the model. property var baseModel: selectObjMode ? - Runtime.Objects.getObjectsName(propertyType.objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Runtime.Objects.types[propertyType.objType].displayType())] : []) + Modules.Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Modules.Objects.types[propertyType.objType].displayType())] : []) : propertyType.values // Translated version of the model. model: selectObjMode ? baseModel : propertyType.translatedValues @@ -198,20 +199,20 @@ Repeater { if(selectObjMode) { // This is only done when what we're selecting are Objects. // Setting object property. - var selectedObj = Runtime.Objects.currentObjectsByName[baseModel[newIndex]] + var selectedObj = Modules.Objects.currentObjectsByName[baseModel[newIndex]] if(newIndex != 0) { // Make sure we don't set the object to null. if(selectedObj == null) { // Creating new object. - selectedObj = Runtime.Objects.createNewRegisteredObject(propertyType.objType) + selectedObj = Modules.Objects.createNewRegisteredObject(propertyType.objType) history.addToHistory(new HistoryLib.CreateNewObject(selectedObj.name, propertyType.objType, selectedObj.export())) - baseModel = Runtime.Objects.getObjectsName(propertyType.objType).concat( - isRealObject ? [qsTr("+ Create new %1").arg(Runtime.Objects.types[propertyType.objType].displayType())] : + baseModel = Modules.Objects.getObjectsName(propertyType.objType).concat( + isRealObject ? [qsTr("+ Create new %1").arg(Modules.Objects.types[propertyType.objType].displayType())] : []) currentIndex = baseModel.indexOf(selectedObj.name) } - selectedObj.requiredBy.push(Runtime.Objects.currentObjects[objType][objIndex]) - //Runtime.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) + selectedObj.requiredBy.push(Modules.Objects.currentObjects[objType][objIndex]) + //Modules.Objects.currentObjects[objType][objIndex].requiredBy = obj[propertyName].filter((obj) => obj.name != obj.name) } obj.requiredBy = obj.requiredBy.filter((obj) => obj.name != obj.name) history.addToHistory(new HistoryLib.EditedProperty( @@ -255,7 +256,7 @@ Repeater { obj.name, objType, propertyName, obj[propertyName], exported )) - //Runtime.Objects.currentObjects[objType][objIndex][propertyName] = exported + //Modules.Objects.currentObjects[objType][objIndex][propertyName] = exported obj[propertyName] = exported root.changed() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml index 2c2b9d0..6f650ef 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/Dialog.qml @@ -52,7 +52,7 @@ Popup.BaseDialog { \qmlproperty var EditorDialog::obj Instance of the object being edited. */ - property var obj: Runtime.Objects.currentObjects[objType][objIndex] + property var obj: Modules.Objects.currentObjects[objType][objIndex] /*! \qmlproperty var EditorDialog::posPicker Reference to the global PositionPicker QML object. @@ -85,7 +85,7 @@ Popup.BaseDialog { Label { id: dlgTitle verticalAlignment: TextInput.AlignVCenter - text: qsTr("Edit properties of %1 %2").arg(Runtime.Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) + text: qsTr("Edit properties of %1 %2").arg(Modules.Objects.types[objEditor.objType].displayType()).arg(objEditor.obj.name) font.pixelSize: 20 color: sysPalette.windowText } @@ -111,14 +111,14 @@ Popup.BaseDialog { onChanged: function(newValue) { let newName = Utils.parseName(newValue) if(newName != '' && objEditor.obj.name != newName) { - if(newName in Runtime.Objects.currentObjectsByName) { + if(newName in Modules.Objects.currentObjectsByName) { invalidNameDialog.showDialog(newName) } else { history.addToHistory(new HistoryLib.NameChanged( objEditor.obj.name, objEditor.objType, newName )) - Runtime.Objects.renameObject(obj.name, newName) - objEditor.obj = Runtime.Objects.currentObjects[objEditor.objType][objEditor.objIndex] + Modules.Objects.renameObject(obj.name, newName) + objEditor.obj = Modules.Objects.currentObjects[objEditor.objType][objEditor.objIndex] objectListList.update() } } @@ -163,7 +163,7 @@ Popup.BaseDialog { */ function open() { dlgCustomProperties.model = [] // Reset - let objProps = Runtime.Objects.types[objEditor.objType].properties() + let objProps = Modules.Objects.types[objEditor.objType].properties() dlgCustomProperties.model = Object.keys(objProps).map(prop => [prop, objProps[prop]]) // Converted to 2-dimentional array. objEditor.show() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml index 6fd42c9..3e621b0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectCreationGrid.qml @@ -43,7 +43,7 @@ Column { // Open editor objectEditor.obj = obj objectEditor.objType = obj.type - objectEditor.objIndex = Runtime.Objects.currentObjects[obj.type].indexOf(obj) + objectEditor.objIndex = Modules.Objects.currentObjects[obj.type].indexOf(obj) objectEditor.open() // Disconnect potential link posPicker.picked.disconnect(openEditorDialog) @@ -60,12 +60,12 @@ Column { width: parent.width columns: 3 Repeater { - model: Object.keys(Runtime.Objects.types) + model: Object.keys(Modules.Objects.types) Button { id: createBtn width: 96 - visible: Runtime.Objects.types[modelData].createable() + visible: Modules.Objects.types[modelData].createable() height: visible ? width*0.8 : 0 // The KDE SDK is kinda buggy, so it respects neither specified color nor display propreties. //display: AbstractButton.TextUnderIcon @@ -93,7 +93,7 @@ Column { anchors.rightMargin: 4 horizontalAlignment: Text.AlignHCenter font.pixelSize: 14 - text: Runtime.Objects.types[modelData].displayType() + text: Modules.Objects.types[modelData].displayType() wrapMode: Text.WordWrap clip: true } @@ -103,7 +103,7 @@ Column { ToolTip.text: label.text onClicked: { - let newObj = Runtime.Objects.createNewRegisteredObject(modelData) + let newObj = Modules.Objects.createNewRegisteredObject(modelData) history.addToHistory(new HistoryLib.CreateNewObject(newObj.name, modelData, newObj.export())) objectLists.update() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml index f7d9e27..d92c36b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectLists.qml @@ -46,7 +46,7 @@ ScrollView { ListView { id: objectsListView - model: Object.keys(Runtime.Objects.types) + model: Object.keys(Modules.Objects.types) //width: implicitWidth //objectListList.width - (implicitHeight > objectListList.parent.height ? 20 : 0) implicitHeight: contentItem.childrenRect.height + footerItem.height + 10 @@ -54,7 +54,7 @@ ScrollView { id: objTypeList property string objType: objectsListView.model[index] property var editingRows: [] - model: Runtime.Objects.currentObjects[objType] + model: Modules.Objects.currentObjects[objType] width: objectsListView.width implicitHeight: contentItem.childrenRect.height visible: model != undefined && model.length > 0 @@ -69,23 +69,23 @@ ScrollView { CheckBox { id: typeVisibilityCheckBox - checked: Runtime.Objects.currentObjects[objType] != undefined ? Runtime.Objects.currentObjects[objType].every(obj => obj.visible) : true + checked: Modules.Objects.currentObjects[objType] != undefined ? Modules.Objects.currentObjects[objType].every(obj => obj.visible) : true onClicked: { - for(var obj of Runtime.Objects.currentObjects[objType]) obj.visible = this.checked + for(var obj of Modules.Objects.currentObjects[objType]) obj.visible = this.checked for(var obj of objTypeList.editingRows) obj.objVisible = this.checked objectListList.changed() } ToolTip.visible: hovered ToolTip.text: checked ? - qsTr("Hide all %1").arg(Runtime.Objects.types[objType].displayTypeMultiple()) : - qsTr("Show all %1").arg(Runtime.Objects.types[objType].displayTypeMultiple()) + qsTr("Hide all %1").arg(Modules.Objects.types[objType].displayTypeMultiple()) : + qsTr("Show all %1").arg(Modules.Objects.types[objType].displayTypeMultiple()) } Label { id: typeHeaderText verticalAlignment: TextInput.AlignVCenter - text: qsTranslate("control", "%1: ").arg(Runtime.Objects.types[objType].displayTypeMultiple()) + text: qsTranslate("control", "%1: ").arg(Modules.Objects.types[objType].displayTypeMultiple()) font.pixelSize: 20 } } @@ -93,11 +93,11 @@ ScrollView { delegate: ObjectRow { id: controlRow width: objTypeList.width - obj: Runtime.Objects.currentObjects[objType][index] + obj: Modules.Objects.currentObjects[objType][index] posPicker: positionPicker onChanged: { - obj = Runtime.Objects.currentObjects[objType][index] + obj = Modules.Objects.currentObjects[objType][index] objectListList.update() } @@ -129,7 +129,7 @@ ScrollView { function update() { objectListList.changed() for(var objType in objectListList.listViews) { - objectListList.listViews[objType].model = Runtime.Objects.currentObjects[objType] + objectListList.listViews[objType].model = Modules.Objects.currentObjects[objType] } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml index cdd9e3a..0772da8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/ObjectRow.qml @@ -89,16 +89,16 @@ Item { id: objDescription anchors.left: objVisibilityCheckBox.right anchors.right: deleteButton.left - height: Runtime.Latex.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight + height: Modules.Latex.enabled ? Math.max(parent.minHeight, latexDescription.height+4) : parent.minHeight verticalAlignment: TextInput.AlignVCenter - text: Runtime.Latex.enabled ? "" : obj.getReadableString() + text: Modules.Latex.enabled ? "" : obj.getReadableString() font.pixelSize: 14 Image { id: latexDescription anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - visible: Runtime.Latex.enabled + visible: Modules.Latex.enabled property double depth: Screen.devicePixelRatio property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color).split(",") : ["","0","0"] source: visible ? ltxInfo[0] : "" @@ -109,7 +109,7 @@ Item { MouseArea { anchors.fill: parent onClicked: { - objEditor.obj = Runtime.Objects.currentObjects[obj.type][index] + objEditor.obj = Modules.Objects.currentObjects[obj.type][index] objEditor.objType = obj.type objEditor.objIndex = index //objEditor.editingRow = objectRow @@ -211,14 +211,14 @@ Item { function deleteRecursively(object) { for(let toRemove of object.requiredBy) deleteRecursively(toRemove) - if(Runtime.Objects.currentObjectsByName[object.name] != undefined) { + if(Modules.Objects.currentObjectsByName[object.name] != undefined) { // Object still exists // Temporary fix for objects require not being propertly updated. object.requiredBy = [] history.addToHistory(new HistoryLib.DeleteObject( object.name, object.type, object.export() )) - Runtime.Objects.deleteObject(object.name) + Modules.Objects.deleteObject(object.name) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml index c92182a..d8a6ac3 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/PickLocationOverlay.qml @@ -113,7 +113,7 @@ Item { if(mouse.button == Qt.LeftButton) { // Validate let newValueX = !parent.userPickX ? null : parseValue(picked.mouseX.toString(), objType, propertyX) let newValueY = !parent.userPickY ? null : parseValue(picked.mouseY.toString(), objType, propertyY) - let obj = Runtime.Objects.currentObjectsByName[objName] + let obj = Modules.Objects.currentObjectsByName[objName] // Set values if(parent.userPickX && parent.userPickY) { history.addToHistory(new HistoryLib.EditedPosition( @@ -262,7 +262,7 @@ Item { color: 'black' anchors.top: parent.top anchors.left: parent.left - anchors.leftMargin: canvas.x2px(picked.mouseX) + anchors.leftMargin: Modules.Canvas.x2px(picked.mouseX) visible: parent.userPickX } @@ -273,7 +273,7 @@ Item { color: 'black' anchors.top: parent.top anchors.left: parent.left - anchors.topMargin: canvas.y2px(picked.mouseY) + anchors.topMargin: Modules.Canvas.y2px(picked.mouseY) visible: parent.userPickY } @@ -282,25 +282,26 @@ Item { x: picker.mouseX - width - 5 y: picker.mouseY - height - 5 color: 'black' - property double axisX: canvas.xaxisstep1 + property double axisX: Modules.Canvas.axesStep.x.value + property double axisY: Modules.Canvas.axesStep.y.value property double mouseX: { - let xpos = canvas.px2x(picker.mouseX) + let xpos = Modules.Canvas.px2x(picker.mouseX) if(snapToGridCheckbox.checked) { if(canvas.logscalex) { // Calculate the logged power let pow = Math.pow(10, Math.floor(Math.log10(xpos))) return pow*Math.round(xpos/pow) } else { - return canvas.xaxisstep1*Math.round(xpos/canvas.xaxisstep1) + return axisX*Math.round(xpos/axisX) } } else { return xpos.toFixed(parent.precision) } } property double mouseY: { - let ypos = canvas.px2y(picker.mouseY) + let ypos = Modules.Canvas.px2y(picker.mouseY) if(snapToGridCheckbox.checked) { - return canvas.yaxisstep1*Math.round(ypos/canvas.yaxisstep1) + return axisY*Math.round(ypos/axisY) } else { return ypos.toFixed(parent.precision) } @@ -323,7 +324,7 @@ Item { Parses a given \c value as an expression or a number depending on the type of \c propertyName of all \c objType. */ function parseValue(value, objType, propertyName) { - if(Runtime.Objects.types[objType].properties()[propertyName] == 'number') + if(Modules.Objects.types[objType].properties()[propertyName] == 'number') return parseFloat(value) else return new MathLib.Expression(value) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index be5160b..ad7e67c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -391,9 +391,9 @@ Item { property string objectName: isEnteringProperty ? (parent.currentToken.dot ? parent.previousToken.value : parent.previousToken2.value) : "" - property bool doesObjectExist: isEnteringProperty && (objectName in Runtime.Objects.currentObjectsByName) + property bool doesObjectExist: isEnteringProperty && (objectName in Modules.Objects.currentObjectsByName) property var objectProperties: doesObjectExist ? - Runtime.Objects.currentObjectsByName[objectName].constructor.properties() : + Modules.Objects.currentObjectsByName[objectName].constructor.properties() : {} categoryItems: Object.keys(objectProperties) autocompleteGenerator: (item) => { @@ -460,9 +460,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: functionsList.itemStartIndex + functionsList.model.length itemSelected: parent.itemSelected - categoryItems: Runtime.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) + categoryItems: Modules.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': Runtime.Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), + 'text': item, 'annotation': Modules.Objects.currentObjectsByName[item] == null ? '' : Objects.currentObjectsByName[item].constructor.displayType(), 'autocomplete': item+'()', 'cursorFinalOffset': -1 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -475,9 +475,9 @@ Item { visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: executableObjectsList.itemStartIndex + executableObjectsList.model.length itemSelected: parent.itemSelected - categoryItems: Object.keys(Runtime.Objects.currentObjectsByName).filter(obj => obj != self) + categoryItems: Object.keys(Modules.Objects.currentObjectsByName).filter(obj => obj != self) autocompleteGenerator: (item) => {return { - 'text': item, 'annotation': `${Runtime.Objects.currentObjectsByName[item].constructor.displayType()}`, + 'text': item, 'annotation': `${Modules.Objects.currentObjectsByName[item].constructor.displayType()}`, 'autocomplete': item+'.', 'cursorFinalOffset': 0 }} baseText: parent.visible ? parent.currentToken.value : "" @@ -537,8 +537,8 @@ Item { throw new Error(qsTranslate('error', 'Object cannot be dependent on itself.')) // Recursive dependencies let dependentOnSelfObjects = expr.requiredObjects().filter( - (obj) => Runtime.Objects.currentObjectsByName[obj].getDependenciesList() - .includes(Runtime.Objects.currentObjectsByName[control.self]) + (obj) => Modules.Objects.currentObjectsByName[obj].getDependenciesList() + .includes(Modules.Objects.currentObjectsByName[control.self]) ) if(dependentOnSelfObjects.length == 1) throw new Error(qsTranslate('error', 'Circular dependency detected. Object %1 depends on %2.').arg(dependentOnSelfObjects[0].toString()).arg(control.self)) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index 2c50c56..b15caed 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -222,10 +222,10 @@ ScrollView { label: qsTr("Max X") icon: "settings/xmax.svg" width: settings.settingWidth - value: canvas.px2x(canvas.canvasSize.width).toFixed(2) + value: Modules.Canvas.px2x(canvas.width).toFixed(2) onChanged: function(xvaluemax) { if(xvaluemax > settings.xmin) { - settings.xzoom = settings.xzoom * canvas.canvasSize.width/(canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.xzoom = settings.xzoom * canvas.width/(Modules.Canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Maximum x value must be superior to minimum.") @@ -241,10 +241,10 @@ ScrollView { label: qsTr("Min Y") icon: "settings/ymin.svg" width: settings.settingWidth - defValue: canvas.px2y(canvas.canvasSize.height).toFixed(2) + defValue: Modules.Canvas.px2y(canvas.height).toFixed(2) onChanged: function(yvaluemin) { if(yvaluemin < settings.ymax) { - settings.yzoom = settings.yzoom * canvas.canvasSize.height/(canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.yzoom = settings.yzoom * canvas.height/(Modules.Canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Minimum y value must be inferior to maximum.") diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml index 85b461e..3d5ff68 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ViewPositionChangeOverlay.qml @@ -94,7 +94,7 @@ Item { property int positionChangeTimer: 0 function updatePosition(deltaX, deltaY) { - settingsInstance.xmin = (canvas.px2x(canvas.x2px(settingsInstance.xmin)-deltaX)) + settingsInstance.xmin = (Modules.Canvas.px2x(Modules.Canvas.x2px(settingsInstance.xmin)-deltaX)) settingsInstance.ymax += deltaY/canvas.yzoom settingsInstance.ymax = settingsInstance.ymax.toFixed(4) settingsInstance.changed() @@ -107,6 +107,7 @@ Item { prevY = mouse.y parent.beginPositionChange() } + onPositionChanged: function(mouse) { positionChangeTimer++ if(positionChangeTimer == 3) { @@ -118,12 +119,14 @@ Item { positionChangeTimer = 0 } } + onReleased: function(mouse) { let deltaX = mouse.x - prevX let deltaY = mouse.y - prevY updatePosition(deltaX, deltaY) parent.endPositionChange(deltaX, deltaY) } + onWheel: function(wheel) { // Scrolling let scrollSteps = Math.round(wheel.angleDelta.y / 120) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js similarity index 87% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js index 773f1c3..4c79c64 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js @@ -5,3 +5,4 @@ .import "objs/autoload.mjs" as Autoload .import "math/latex.mjs" as Latex .import "history/common.mjs" as HistoryCommon +.import "canvas.mjs" as CanvasAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs new file mode 100644 index 0000000..d68bd9d --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -0,0 +1,523 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {Module} from "./modules.mjs" +import {textsup} from "./utils.mjs" +import {Expression} from "./mathlib.mjs" + + +class CanvasAPI extends Module { + + constructor() { + super('Canvas', [ + Modules.Objects, + Modules.History + ]) + + /** @type {HTMLCanvasElement} */ + this._canvas = null + + /** @type {CanvasRenderingContext2D} */ + this._ctx = null + + /** + * @type {Object} + * @property {function(string, string, string)} showDialog + * @private + */ + this._drawingErrorDialog = null + /** + * + * @type {Object.} + */ + this.axesSteps = { + x: { + expression: null, + value: -1, + maxDraw: -1 + }, + y: { + expression: null, + value: -1, + maxDraw: -1 + } + } + } + + initialize(canvasObject, drawingErrorDialog) { + this._canvas = canvasObject + this._drawingErrorDialog = drawingErrorDialog + } + + get width() { return this._canvas.width } + + get height() { return this._canvas.height } + + /** + * Minimum x of the diagram, provided from settings. + * @returns {number} + */ + get xmin() { return this._canvas.xmin } + + /** + * Zoom on the x-axis of the diagram, provided from settings. + * @returns {number} + */ + get xzoom() { return this._canvas.xzoom } + + /** + * Maximum y of the diagram, provided from settings. + * @returns {number} + */ + get ymax() { return this._canvas.ymax } + + /** + * Zoom on the y-axis of the diagram, provided from settings. + * @returns {number} + */ + get yzoom() { return this._canvas.yzoom } + + /** + * Label used on the x-axis, provided from settings. + * @returns {string} + */ + get xlabel() { return this._canvas.xlabel } + + /** + * Label used on the y-axis, provided from settings. + * @returns {string} + */ + get ylabel() { return this._canvas.ylabel } + + /** + * Width of lines that will be drawn into the canvas, provided from settings. + * @returns {number} + */ + get linewidth() { return this._canvas.linewidth } + + /** + * Font size of the text that will be drawn into the canvas, provided from settings. + * @returns {number} + */ + get textsize() { return this._canvas.textsize } + + /** + * True if the canvas should be in logarithmic mode, false otherwise. + * @returns {boolean} + */ + get logscalex() { return this._canvas.logscalex } + + /** + * True if the x graduation should be shown, false otherwise. + * @returns {boolean} + */ + get showxgrad() { return this._canvas.showxgrad } + + /** + * True if the y graduation should be shown, false otherwise. + * @returns {boolean} + */ + get showygrad() { return this._canvas.showygrad } + + /** + * Max power of the logarithmic scaled on the x axis in logarithmic mode. + * @returns {number} + */ + get maxgradx() { return this._canvas.maxgradx } + + // + // Methods to draw the canvas + // + + /** + * Redraws the entire canvas + */ + redraw() { + this._ctx = this._canvas.getContext("2d") + this._computeAxes() + this._reset() + this._drawGrid() + this._drawAxes() + this._drawLabels() + this._ctx.lineWidth = this.linewidth + for(let objType in Modules.Objects.currentObjects) { + for(let obj of Modules.Objects.currentObjects[objType]){ + this._ctx.strokeStyle = obj.color + this._ctx.fillStyle = obj.color + if(obj.visible) + try { + obj.draw(this) + } catch(e) { + // Drawing throws an error. Generally, it's due to a new modification (or the opening of a file) + this._drawingErrorDialog.showDialog(objType, obj.name, e.message) + Modules.History.undo() + } + } + } + this._ctx.lineWidth = 1 + } + + /** + * Calculates informations for drawing gradations for axes. + * @private + */ + _computeAxes() { + let exprY = new Expression(`x*(${this._canvas.yaxisstep})`) + let y1 = exprY.execute(1) + let exprX = new Expression(`x*(${this._canvas.xaxisstep})`) + let x1 = exprX.execute(1) + this.axesSteps = { + x: { + expression: exprX, + value: x1, + maxDraw: Math.ceil(Math.max(Math.abs(this.xmin), Math.abs(this.px2x(this.width)))/x1) + }, + y: { + expression: exprY, + value: y1, + maxDraw: Math.ceil(Math.max(Math.abs(this.ymax), Math.abs(this.px2y(this.height)))/y1) + } + } + } + + /** + * Resets the canvas to a blank one with default setting. + * @private + */ + _reset(){ + // Reset + this._ctx.fillStyle = "#FFFFFF" + this._ctx.strokeStyle = "#000000" + this._ctx.font = `${this.textsize}px sans-serif` + this._ctx.fillRect(0,0,this.width,this.height) + } + + /** + * Draws the grid. + * @private + */ + _drawGrid() { + this._ctx.strokeStyle = "#C0C0C0" + if(this.logscalex) { + for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow++) { + for(let xmulti = 1; xmulti < 10; xmulti++) { + this.drawXLine(Math.pow(10, xpow)*xmulti) + } + } + } else { + for(let x = 0; x < this.axesSteps.x.maxDraw; x+=1) { + this.drawXLine(x*this.axesSteps.x.value) + this.drawXLine(-x*this.axesSteps.x.value) + } + } + for(let y = 0; y < this.axesSteps.y.maxDraw; y+=1) { + this.drawYLine(y*this.axesSteps.y.value) + this.drawYLine(-y*this.axesSteps.y.value) + } + } + + /** + * Draws the graph axes. + * @private + */ + _drawAxes() { + this._ctx.strokeStyle = "#000000" + let axisypos = this.logscalex ? 1 : 0 + this.drawXLine(axisypos) + this.drawYLine(0) + let axisypx = this.x2px(axisypos) // X coordinate of Y axis + let axisxpx = this.y2px(0) // Y coordinate of X axis + // Drawing arrows + this.drawLine(axisypx, 0, axisypx-10, 10) + this.drawLine(axisypx, 0, axisypx+10, 10) + this.drawLine(this.width, axisxpx, this.width-10, axisxpx-10) + this.drawLine(this.width, axisxpx, this.width-10, axisxpx+10) + } + + /** + * Resets the canvas to a blank one with default setting. + * @private + */ + _drawLabels() { + let axisypx = this.x2px(this.logscalex ? 1 : 0) // X coordinate of Y axis + let axisxpx = this.y2px(0) // Y coordinate of X axis + // Labels + this._ctx.fillStyle = "#000000" + this._ctx.font = `${this.textsize}px sans-serif` + this._ctx.fillText(this.ylabel, axisypx+10, 24) + let textWidth = this._ctx.measureText(this.xlabel).width + this._ctx.fillText(this.xlabel, this.width-14-textWidth, axisxpx-5) + // Axis graduation labels + this._ctx.font = `${this.textsize-4}px sans-serif` + + let txtMinus = this._ctx.measureText('-').width + if(this.showxgrad) { + if(this.logscalex) { + for(let xpow = -this.maxgradx; xpow <= this.maxgradx; xpow+=1) { + textWidth = this._ctx.measureText("10"+textsup(xpow)).width + if(xpow !== 0) + this.drawVisibleText("10"+textsup(xpow), this.x2px(Math.pow(10,xpow))-textWidth/2, axisxpx+16+(6*(xpow===1))) + } + } else { + for(let x = 1; x < this.axesSteps.x.maxDraw; x += 1) { + let drawX = x*this.axesSteps.x.value + let txtX = this.axesSteps.x.expression.simplify(x).replace(/^\((.+)\)$/, '$1') + let textHeight = this.measureText(txtX).height + this.drawVisibleText(txtX, this.x2px(drawX)-4, axisxpx+this.textsize/2+textHeight) + this.drawVisibleText('-'+txtX, this.x2px(-drawX)-4, axisxpx+this.textsize/2+textHeight) + } + } + } + if(this.showygrad) { + for(let y = 0; y < this.axesSteps.y.maxDraw; y += 1) { + let drawY = y*this.axesSteps.y.value + let txtY = this.axesSteps.y.expression.simplify(y).replace(/^\((.+)\)$/, '$1') + textWidth = this._ctx.measureText(txtY).width + this.drawVisibleText(txtY, axisypx-6-textWidth, this.y2px(drawY)+4+(10*(y===0))) + if(y !== 0) + this.drawVisibleText('-'+txtY, axisypx-6-textWidth-txtMinus, this.y2px(-drawY)+4) + } + } + this._ctx.fillStyle = "#FFFFFF" + } + + // + // Public functions + // + + /** + * Draws an horizontal line at x plot coordinate. + * @param {number} x + */ + drawXLine(x) { + if(this.isVisible(x, this.ymax)) { + this.drawLine(this.x2px(x), 0, this.x2px(x), this.height) + } + } + + /** + * Draws an vertical line at y plot coordinate + * @param {number} y + * @private + */ + drawYLine(y) { + if(this.isVisible(this.xmin, y)) { + this.drawLine(0, this.y2px(y), this.width, this.y2px(y)) + } + } + + /** + * Writes multiline text onto the canvas. + * NOTE: The x and y properties here are relative to the canvas, not the plot. + * @param {string} text + * @param {number} x + * @param {number} y + */ + drawVisibleText(text, x, y) { + if(x > 0 && x < this.width && y > 0 && y < this.height) { + text.toString().split("\n").forEach((txt, i) => { + this._ctx.fillText(txt, x, y+(this.textsize*i)) + }) + } + } + + /** + * Draws an image onto the canvas. + * NOTE: The x, y width and height properties here are relative to the canvas, not the plot. + * @param {CanvasImageSource} image + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + */ + drawVisibleImage(image, x, y, width, height) { + this._canvas.markDirty(Qt.rect(x, y, width, height)); + this._ctx.drawImage(image, x, y, width, height) + } + + /** + * Measures the width and height of a multiline text that would be drawn onto the canvas. + * @param {string} text + * @returns {{width: number, height: number}} + */ + measureText(text) { + let theight = 0 + let twidth = 0 + let defaultHeight = this.textsize * 1.2 // Approximate but good enough! + for(let txt of text.split("\n")) { + theight += defaultHeight + if(this._ctx.measureText(txt).width > twidth) twidth = this._ctx.measureText(txt).width + } + return {'width': twidth, 'height': theight} + } + + /** + * Converts an x coordinate to its relative position on the canvas. + * It supports both logarithmic and non-logarithmic scale depending on the currently selected mode. + * @param {number} x + * @returns {number} + */ + x2px(x) { + if(this.logscalex) { + let logxmin = Math.log(this.xmin) + return (Math.log(x)-logxmin)*this.xzoom + } else return (x - this.xmin)*this.xzoom + } + + /** + * Converts an y coordinate to it's relative position on the canvas. + * The y-axis not supporting logarithmic scale, it only supports linear conversion. + * @param {number} y + * @returns {number} + */ + y2px(y) { + return (this.ymax-y)*this.yzoom + } + + /** + * Converts an x px position on the canvas to it's corresponding coordinate on the plot. + * It supports both logarithmic and non-logarithmic scale depending on the currently selected mode. + * @param {number} px + * @returns {number} + */ + px2x(px) { + if(this.logscalex) { + return Math.exp(px/this.xzoom+Math.log(this.xmin)) + } else return (px/this.xzoom+this.xmin) + } + + /** + * Converts an x px position on the canvas to it's corresponding coordinate on the plot. + * It supports both logarithmic and non logarithmic scale depending on the currently selected mode. + * @param {number} px + * @returns {number} + */ + px2y(px) { + return -(px/this.yzoom-this.ymax) + } + + /** + * Checks whether a plot point (x, y) is visible or not on the canvas. + * @param {number} x + * @param {number} y + * @returns {boolean} + */ + isVisible(x, y) { + return (this.x2px(x) >= 0 && this.x2px(x) <= this.width) && (this.y2px(y) >= 0 && this.y2px(y) <= this.height) + } + + /** + * Draws a line from plot point (x1, y1) to plot point (x2, y2). + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + */ + drawLine(x1, y1, x2, y2) { + this._ctx.beginPath(); + this._ctx.moveTo(x1, y1); + this._ctx.lineTo(x2, y2); + this._ctx.stroke(); + } + + /** + * Draws a dashed line from plot point (x1, y1) to plot point (x2, y2). + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} dashPxSize + */ + drawDashedLine(x1, y1, x2, y2, dashPxSize = 6) { + this._ctx.setLineDash([dashPxSize/2, dashPxSize]); + this.drawLine(x1, y1, x2, y2) + this._ctx.setLineDash([]); + } + + /** + * Renders latex markup ltxText to an image and loads it. Returns a dictionary with three values: source, width and height. + * @param {string} ltxText + * @param {string} color + * @param {function({width: number, height: number, source: string})} callback + */ + renderLatexImage(ltxText, color, callback) { + let [ltxSrc, ltxWidth, ltxHeight] = Latex.render(ltxText, this.textsize, color).split(",") + let imgData = { + "source": ltxSrc, + "width": parseFloat(ltxWidth), + "height": parseFloat(ltxHeight) + }; + if(!this._canvas.isImageLoaded(ltxSrc) && !this._canvas.isImageLoading(ltxSrc)){ + // Wait until the image is loaded to callback. + this._canvas.loadImage(ltxSrc) + this._canvas.imageLoaders[ltxSrc] = [callback, imgData] + } else { + // Callback directly + callback(imgData) + } + } + + // + // Context methods + // + + get font() { return this._ctx.font } + set font(value) { return this._ctx.font = value } + + /** + * Draws an act on the canvas centered on a point. + * @param {number} x + * @param {number} y + * @param {number} radius + * @param {number} startAngle + * @param {number} endAngle + * @param {boolean} counterclockwise + */ + arc(x, y, radius, startAngle, endAngle, counterclockwise=false) { + this._ctx.beginPath() + this._ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise) + this._ctx.stroke() + } + + /** + * Draws a filled circle centered on a point. + * @param {number} x + * @param {number} y + * @param {number} radius + */ + disc(x, y, radius) { + this._ctx.beginPath(); + this._ctx.arc(x, y, radius, 0, 2 * Math.PI) + this._ctx.fill(); + } + + /** + * Draws a filled rectangle onto the canvas. + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + */ + fillRect(x, y, w, h) { + this._ctx.fillRect(x, y, w, h) + } +} + +/** @type {CanvasAPI} */ +Modules.Canvas = Modules.Canvas || new CanvasAPI() +export const API = Modules.Canvas \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 78476ca..b662098 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -16,14 +16,14 @@ * along with this program. If not, see . */ -import { RuntimeAPI } from "../runtime.mjs" +import { Module } from "../modules.mjs" import Latex from "../math/latex.mjs" -class HistoryCommonAPI extends RuntimeAPI { +class HistoryCommonAPI extends Module { constructor() { super('History', [ - Runtime.Latex + Modules.Latex ]) // History QML object this.history = null; @@ -31,12 +31,16 @@ class HistoryCommonAPI extends RuntimeAPI { this.imageDepth = 2; this.fontSize = 14; } + + undo() { this.history.undo() } + redo() { this.history.redo() } + addToHistory(action) { this.history.addToHistory(action) } } /** @type {HistoryCommonAPI} */ -Runtime.History = Runtime.History || new HistoryCommonAPI() +Modules.History = Modules.History || new HistoryCommonAPI() -export const API = Runtime.History +export const API = Modules.History export class Action { /** @@ -95,7 +99,7 @@ export class Action { * @returns {string} */ getIconRichText(type) { - return `` + return `` } /** @@ -107,11 +111,11 @@ export class Action { renderLatexAsHtml(latexString) { if(!Latex.enabled) throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.") - let imgDepth = Runtime.History.imageDepth + let imgDepth = Modules.History.imageDepth let [src, width, height] = Latex.render( latexString, - imgDepth * (Runtime.History.fontSize + 2), - Runtime.History.themeTextColor + imgDepth * (Modules.History.fontSize + 2), + Modules.History.themeTextColor ).split(",") return `` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js index 68a88c1..998ed32 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/expr-eval/integration.js @@ -19,9 +19,7 @@ .pragma library .import "expr-eval.js" as ExprEval -.import "../../runtime.mjs" as R - -let RuntimeAPI = R.RuntimeAPI +.import "../../modules.mjs" as M const evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manually @@ -38,11 +36,11 @@ const evalVariables = { "false": false } -class ExprParserAPI extends RuntimeAPI { +class ExprParserAPI extends M.Module { constructor() { super('ExprParser', [ /** @type {ObjectsAPI} */ - Runtime.Objects + Modules.Objects ]) this.currentVars = {} this.Internals = ExprEval @@ -115,7 +113,7 @@ class ExprParserAPI extends RuntimeAPI { } /** @type {ExprParserAPI} */ -Runtime.ExprParser = Runtime.ExprParser || new ExprParserAPI() +Modules.ExprParser = Modules.ExprParser || new ExprParserAPI() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index a940967..5302aca 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -19,7 +19,7 @@ // Type polyfills for IDEs. // Never directly imported. -Runtime = Runtime || {} +Modules = Modules || {} /** @type {function(string, string): string} */ qsTranslate = qsTranslate || function(category, string) { throw new Error('qsTranslate not implemented.'); } /** @type {function(string): string} */ @@ -29,6 +29,19 @@ QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Er /** @type {function(string|boolean|int): string} */ String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } +const Qt = { + /** + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @returns {{x, width, y, height}} + */ + rect: function(x, y, width, height) { + return {x: x, y: y, width: width, height: height}; + } +} + /** Typehints for Helper. */ const Helper = { /** @type {function(string): boolean} */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs index 3a16499..66cd044 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/expression.mjs @@ -25,16 +25,16 @@ import * as Utils from "../utils.mjs" */ export class Expression { constructor(expr) { - if(!Runtime.ExprParser) + if(!Modules.ExprParser) throw new Error('Expression parser not initialized.') - if(!Runtime.Objects) + if(!Modules.Objects) throw new Error('Objects API not initialized.') this.expr = Utils.exponentsToExpression(expr) - this.calc = Runtime.ExprParser.parse(this.expr).simplify() + this.calc = Modules.ExprParser.parse(this.expr).simplify() this.cached = this.isConstant() this.cachedValue = null if(this.cached && this.allRequirementsFullfilled()) - this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) this.latexMarkup = Latex.expression(this.calc.tokens) } @@ -48,26 +48,26 @@ export class Expression { } allRequirementsFullfilled() { - return this.requiredObjects().every(objName => objName in Runtime.Objects.currentObjectsByName) + return this.requiredObjects().every(objName => objName in Modules.Objects.currentObjectsByName) } undefinedVariables() { - return this.requiredObjects().filter(objName => !(objName in Runtime.Objects.currentObjectsByName)) + return this.requiredObjects().filter(objName => !(objName in Modules.Objects.currentObjectsByName)) } recache() { if(this.cached) - this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) } execute(x = 1) { if(this.cached) { if(this.cachedValue == null) - this.cachedValue = this.calc.evaluate(Runtime.Objects.currentObjectsByName) + this.cachedValue = this.calc.evaluate(Modules.Objects.currentObjectsByName) return this.cachedValue } - Runtime.ExprParser.currentVars = Object.assign({'x': x}, Runtime.Objects.currentObjectsByName) - return this.calc.evaluate(Runtime.ExprParser.currentVars) + Modules.ExprParser.currentVars = Object.assign({'x': x}, Modules.Objects.currentObjectsByName) + return this.calc.evaluate(Modules.ExprParser.currentVars) } simplify(x) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs index ef1f862..7418b9c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/latex.mjs @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { RuntimeAPI } from '../runtime.mjs' +import { Module } from '../modules.mjs' const unicodechars = ["α","β","γ","δ","ε","ζ","η", "π","θ","κ","λ","μ","ξ","ρ", @@ -39,13 +39,12 @@ const equivalchars = ["\\alpha","\\beta","\\gamma","\\delta","\\epsilon","\\zeta "{}_{4}","{}_{5}","{}_{6}","{}_{7}","{}_{8}","{}_{9}","{}_{0}", "\\pi", "\\infty"] -console.log(Runtime.ExprParser) - -class LatexAPI extends RuntimeAPI { + +class LatexAPI extends Module { constructor() { super('Latex', [ /** @type {ExprParserAPI} */ - Runtime.ExprParser + Modules.ExprParser ]) /** * true if latex has been enabled by the user, false otherwise. @@ -161,18 +160,18 @@ class LatexAPI extends RuntimeAPI { let type = item.type switch(type) { - case Runtime.ExprParser.Internals.INUMBER: + case Modules.ExprParser.Internals.INUMBER: if(item.value === Infinity) { nstack.push("\\infty") } else if(typeof item.value === 'number' && item.value < 0) { nstack.push(this.par(item.value)); } else if(Array.isArray(item.value)) { - nstack.push('[' + item.value.map(Runtime.ExprParser.Internals.escapeValue).join(', ') + ']'); + nstack.push('[' + item.value.map(Modules.ExprParser.Internals.escapeValue).join(', ') + ']'); } else { - nstack.push(Runtime.ExprParser.Internals.escapeValue(item.value)); + nstack.push(Modules.ExprParser.Internals.escapeValue(item.value)); } break; - case Runtime.ExprParser.Internals.IOP2: + case Modules.ExprParser.Internals.IOP2: n2 = nstack.pop(); n1 = nstack.pop(); f = item.value; @@ -211,7 +210,7 @@ class LatexAPI extends RuntimeAPI { throw new EvalError("Unknown operator " + ope + "."); } break; - case Runtime.ExprParser.Internals.IOP3: // Thirdiary operator + case Modules.ExprParser.Internals.IOP3: // Thirdiary operator n3 = nstack.pop(); n2 = nstack.pop(); n1 = nstack.pop(); @@ -222,11 +221,11 @@ class LatexAPI extends RuntimeAPI { throw new EvalError('Unknown operator ' + ope + '.'); } break; - case Runtime.ExprParser.Internals.IVAR: - case Runtime.ExprParser.Internals.IVARNAME: + case Modules.ExprParser.Internals.IVAR: + case Modules.ExprParser.Internals.IVARNAME: nstack.push(this.variable(item.value.toString())); break; - case Runtime.ExprParser.Internals.IOP1: // Unary operator + case Modules.ExprParser.Internals.IOP1: // Unary operator n1 = nstack.pop(); f = item.value; switch(f) { @@ -242,7 +241,7 @@ class LatexAPI extends RuntimeAPI { break; } break; - case Runtime.ExprParser.Internals.IFUNCALL: + case Modules.ExprParser.Internals.IFUNCALL: argCount = item.value; args = []; while (argCount-- > 0) { @@ -252,14 +251,14 @@ class LatexAPI extends RuntimeAPI { // Handling various functions nstack.push(this.functionToLatex(f, args)) break; - case Runtime.ExprParser.Internals.IFUNDEF: + case Modules.ExprParser.Internals.IFUNDEF: nstack.push(this.par(n1 + '(' + args.join(', ') + ') = ' + n2)); break; - case Runtime.ExprParser.Internals.IMEMBER: + case Modules.ExprParser.Internals.IMEMBER: n1 = nstack.pop(); nstack.push(n1 + '.' + item.value); break; - case Runtime.ExprParser.Internals.IARRAY: + case Modules.ExprParser.Internals.IARRAY: argCount = item.value; args = []; while (argCount-- > 0) { @@ -267,10 +266,10 @@ class LatexAPI extends RuntimeAPI { } nstack.push('[' + args.join(', ') + ']'); break; - case Runtime.ExprParser.Internals.IEXPR: + case Modules.ExprParser.Internals.IEXPR: nstack.push('(' + this.expression(item.value) + ')'); break; - case Runtime.ExprParser.Internals.IENDSTATEMENT: + case Modules.ExprParser.Internals.IENDSTATEMENT: break; default: throw new EvalError('invalid Expression'); @@ -284,6 +283,6 @@ class LatexAPI extends RuntimeAPI { } /** @type {LatexAPI} */ -Runtime.Latex = Runtime.Latex || new LatexAPI() +Modules.Latex = Modules.Latex || new LatexAPI() -export default Runtime.Latex +export default Modules.Latex diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs index 2dafdcd..a1a96cd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/math/sequence.mjs @@ -33,7 +33,7 @@ export class Sequence extends Expr.Expression { this.latexValues = Object.assign({}, baseValues) for(let n in this.calcValues) if(['string', 'number'].includes(typeof this.calcValues[n])) { - let parsed = Runtime.ExprParser.parse(this.calcValues[n].toString()).simplify() + let parsed = Modules.ExprParser.parse(this.calcValues[n].toString()).simplify() this.latexValues[n] = Latex.expression(parsed.tokens) this.calcValues[n] = parsed.evaluate() } @@ -60,17 +60,17 @@ export class Sequence extends Expr.Expression { cache(n = 1) { let str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) - let expr = Runtime.ExprParser.parse(str).simplify() + let expr = Modules.ExprParser.parse(str).simplify() // Cache values required for this one. if(!this.calcValues[n-this.valuePlus] && n-this.valuePlus > 0) this.cache(n-this.valuePlus) // Setting current variables - Runtime.ExprParser.currentVars = Object.assign( + Modules.ExprParser.currentVars = Object.assign( {'n': n-this.valuePlus}, // Just in case, add n (for custom functions) - Runtime.Objects.currentObjectsByName, + Modules.Objects.currentObjectsByName, {[this.name]: this.calcValues} ) - this.calcValues[n] = expr.evaluate(Runtime.ExprParser.currentVars) + this.calcValues[n] = expr.evaluate(Modules.ExprParser.currentVars) } toString(forceSign=false) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.mjs similarity index 89% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.mjs index 0d859aa..1b68b89 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/runtime.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/modules.mjs @@ -19,12 +19,12 @@ /** * Base class for global APIs in runtime. */ -export class RuntimeAPI { +export class Module { /** * * @param {string} name - Name of the API - * @param {(RuntimeAPI|undefined)[]} requires - List of APIs required to initialize this one. + * @param {(Module|undefined)[]} requires - List of APIs required to initialize this one. */ constructor(name, requires = []) { console.log(`Loading module ${name}...`) @@ -33,7 +33,7 @@ export class RuntimeAPI { /** * Checks if all requirements are defined. - * @param {(RuntimeAPI|undefined)[]} requires + * @param {(Module|undefined)[]} requires * @param {string} name */ __check_requirements(requires, name) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs index b7a2dae..c45b65e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objects.mjs @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -import { RuntimeAPI } from './runtime.mjs' +import { Module } from './modules.mjs' -class ObjectsAPI extends RuntimeAPI { +class ObjectsAPI extends Module { constructor() { super('Objects') @@ -107,6 +107,6 @@ class ObjectsAPI extends RuntimeAPI { } /** @type {ObjectsAPI} */ -Runtime.Objects = Runtime.Objects || new ObjectsAPI() +Modules.Objects = Modules.Objects || new ObjectsAPI() -export default Runtime.Objects +export default Modules.Objects diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs index c3e8f63..f29710b 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/autoload.mjs @@ -28,7 +28,7 @@ import XCursor from "xcursor.mjs" import Sequence from "sequence.mjs" import RepartitionFunction from "repartition.mjs" -if(Object.keys(Runtime.Objects.types).length === 0) { +if(Object.keys(Modules.Objects.types).length === 0) { ObjectsCommonAPI.registerObject(Point) ObjectsCommonAPI.registerObject(Text) ObjectsCommonAPI.registerObject(Function) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 7821037..5fb31ba 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -19,17 +19,17 @@ import { getRandomColor, textsub } from "../utils.mjs" import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" -import {RuntimeAPI} from "../runtime.mjs" +import {Module} from "../modules.mjs" // This file contains the default data to be imported from all other objects -class ObjectsCommonAPI extends RuntimeAPI { +class ObjectsCommonAPI extends Module { constructor() { super('ObjectsCommon', [ - Runtime.Objects, - Runtime.ExprParser, - Runtime.Latex + Modules.Objects, + Modules.ExprParser, + Modules.Latex ]) } @@ -72,9 +72,9 @@ class ObjectsCommonAPI extends RuntimeAPI { } /** @type {ObjectsCommonAPI} */ -Runtime.ObjectsCommon = Runtime.ObjectsCommon || new ObjectsCommonAPI() +Modules.ObjectsCommon = Modules.ObjectsCommon || new ObjectsCommonAPI() -export const API = Runtime.ObjectsCommon +export const API = Modules.ObjectsCommon /** * Class to extend for every type of object that @@ -269,18 +269,17 @@ export class DrawableObject { for(let toRemove of this.requiredBy) { // Normally, there should be none here, but better leave nothing just in case. Objects.deleteObject(toRemove.name) } - console.log(this.requires) for(let toRemoveFrom of this.requires) { toRemoveFrom.requiredBy = toRemoveFrom.requiredBy.filter(o => o !== this) } } /** - * Abstract method. Draw the object onto the \c canvas with the 2D context \c ctx. - * @param {Canvas} canvas + * Abstract method. Draw the object onto the \c canvas with the. + * @param {CanvasAPI} canvas * @param {CanvasRenderingContext2D} ctx */ - draw(canvas, ctx) {} + draw(canvas) {} /** * Applicates a \c drawFunction with two position arguments depending on @@ -343,7 +342,7 @@ export class DrawableObject { * Then, it's displayed using the \c drawFunctionLatex (x,y,imageData) and * \c drawFunctionText (x,y,text) depending on whether to use latex. * - * @param {Canvas} canvas + * @param {CanvasAPI} canvas * @param {CanvasRenderingContext2D} ctx * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} posX - Component of the marked position on the x-axis @@ -354,7 +353,7 @@ export class DrawableObject { * @param {function|null} drawFunctionLatex - Function (x,y,imageData) to display the latex image * @param {function|null} drawFunctionText - Function (x,y,text,textSize) to display the text */ - drawLabel(canvas, ctx, labelPosition, posX, posY,forceText = false, + drawLabel(canvas, labelPosition, posX, posY,forceText = false, getLatexFunction = null, getTextFunction = null, drawFunctionLatex = null, drawFunctionText = null) { // Default functions if(getLatexFunction == null) @@ -362,25 +361,25 @@ export class DrawableObject { if(getTextFunction == null) getTextFunction = this.getLabel.bind(this) if(drawFunctionLatex == null) - drawFunctionLatex = (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height) + drawFunctionLatex = (x,y,ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, y, ltxImg.width, ltxImg.height) if(drawFunctionText == null) - drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, y+textSize.height) // Positioned from left bottom + drawFunctionText = (x,y,text,textSize) => canvas.drawVisibleText(text, x, y+textSize.height) // Positioned from left bottom // Drawing the label let offset if(!forceText && Latex.enabled) { // With latex - let drawLblCb = function(canvas, ctx, ltxImg) { - this.drawPositionDivergence(labelPosition, 8+ctx.lineWidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) - } + let drawLblCb = ((ltxImg) => { + this.drawPositionDivergence(labelPosition, 8+canvas.linewidth/2, ltxImg, posX, posY, (x,y) => drawFunctionLatex(x,y,ltxImg)) + }).bind(this) let ltxLabel = getLatexFunction(); - if(ltxLabel != "") + if(ltxLabel !== "") canvas.renderLatexImage(ltxLabel, this.color, drawLblCb.bind(this)) } else { // Without latex let text = getTextFunction() - ctx.font = `${canvas.textsize}px sans-serif` - let textSize = canvas.measureText(ctx, text) - this.drawPositionDivergence(labelPosition, 8+ctx.lineWidth/2, textSize, posX, posY, (x,y) => drawFunctionText(x,y,text,textSize)) + canvas.font = `${canvas.textsize}px sans-serif` + let textSize = canvas.measureText(text) + this.drawPositionDivergence(labelPosition, 8+canvas.linewidth/2, textSize, posX, posY, (x,y) => drawFunctionText(x,y,text,textSize)) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 1a52dba..0d68830 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -104,17 +104,17 @@ export default class Function extends ExecutableObject { return '' } - draw(canvas, ctx) { - Function.drawFunction(canvas, ctx, this.expression, this.definitionDomain, this.destinationDomain, this.drawPoints, this.drawDashedLines) + draw(canvas) { + Function.drawFunction(canvas, this.expression, this.definitionDomain, this.destinationDomain, this.drawPoints, this.drawDashedLines) // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } /** * Reusable in other objects. * Drawing small traits every few pixels */ - static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { + static drawFunction(canvas, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { let pxprecision = 10 let previousX = canvas.px2x(0) let previousY = null; @@ -124,7 +124,7 @@ export default class Function extends ExecutableObject { if(previousX === null) previousX = definitionDomain.next(canvas.px2x(0)) previousY = expr.execute(previousX) if(!drawPoints && !drawDash) return - while(previousX !== null && canvas.x2px(previousX) < canvas.canvasSize.width) { + while(previousX !== null && canvas.x2px(previousX) < canvas.width) { // Reconverted for canvas to fix for logarithmic scales. let currentX = definitionDomain.next(canvas.px2x(canvas.x2px(previousX)+pxprecision)); let currentY = expr.execute(currentX) @@ -132,10 +132,10 @@ export default class Function extends ExecutableObject { if((definitionDomain.includes(currentX) || definitionDomain.includes(previousX)) && (destinationDomain.includes(currentY) || destinationDomain.includes(previousY))) { if(drawDash) - canvas.drawDashedLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) + canvas.drawDashedLine(canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) if(drawPoints) { - ctx.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) - ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) + canvas.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) + canvas.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) } } previousX = currentX @@ -143,8 +143,8 @@ export default class Function extends ExecutableObject { } if(drawPoints) { // Drawing the last cross - ctx.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) - ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) + canvas.fillRect(canvas.x2px(previousX)-5, canvas.y2px(previousY)-1, 10, 2) + canvas.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) } } else { // Use max precision if function is trigonometrical on log scale. @@ -154,7 +154,7 @@ export default class Function extends ExecutableObject { // Calculate the previousY at the start of the canvas if(definitionDomain.includes(previousX)) previousY = expr.execute(previousX) - for(let px = pxprecision; px < canvas.canvasSize.width; px += pxprecision) { + for(let px = pxprecision; px < canvas.width; px += pxprecision) { let currentX = canvas.px2x(px) if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { // Should draw up to currentX, but NOT at previousX. @@ -176,12 +176,12 @@ export default class Function extends ExecutableObject { } while(!definitionDomain.includes(currentX) && currentX !== previousX) } // This max variation is needed for functions with asymptotical vertical lines (e.g. 1/x, tan x...) - let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.canvasSize.height)) + let maxvariation = (canvas.px2y(0)-canvas.px2y(canvas.height)) if(definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) { let currentY = expr.execute(currentX) if(destinationDomain.includes(currentY)) { if(previousY != null && destinationDomain.includes(previousY) && Math.abs(previousY-currentY) < maxvariation) { - canvas.drawLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) + canvas.drawLine(canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) } } previousY = currentY diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs index 696084d..fb0e9cd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs @@ -40,7 +40,7 @@ export default class GainBode extends ExecutableObject { [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', [QT_TRANSLATE_NOOP('prop','omGraduation')]: 'boolean' }} - + constructor(name = null, visible = true, color = null, labelContent = 'name + value', om_0 = '', pass = 'high', gain = '20', labelPosition = 'above', labelX = 1, omGraduation = false) { if(name == null) name = Common.getNewName('G') @@ -52,12 +52,13 @@ export default class GainBode extends ExecutableObject { if(om_0 == null) { // Create new point om_0 = Objects.createNewRegisteredObject('Point', [Common.getNewName('ω'), true, this.color, 'name']) - HistoryAPI.history.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) + HistoryAPI.addToHistory(new CreateNewObject(om_0.name, 'Point', om_0.export())) om_0.update() labelPosition = 'below' } om_0.requiredBy.push(this) } + /** @type {Point} */ this.om_0 = om_0 this.pass = pass if(typeof gain == 'number' || typeof gain == 'string') gain = new Expression(gain.toString()) @@ -98,7 +99,7 @@ export default class GainBode extends ExecutableObject { simplify(x = 1) { let xval = x if(typeof x == 'string') xval = executeExpression(x) - if((this.pass === 'high' && xval < this.om_0.x) || (this.pass === 'low' && xval > this.om_0.x)) { + if((this.pass === 'high' && xval < this.om_0.x.execute()) || (this.pass === 'low' && xval > this.om_0.x.execute())) { let dbfn = new Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`) return dbfn.simplify(x) } else { @@ -110,29 +111,29 @@ export default class GainBode extends ExecutableObject { return true } - draw(canvas, ctx) { - let base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)] + draw(canvas) { + let base = [canvas.x2px(this.om_0.x.execute()), canvas.y2px(this.om_0.y.execute())] let dbfn = new Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`) let inDrawDom = new EmptySet() if(this.pass === 'high') { // High pass, linear line from beginning, then constant to the end. - canvas.drawLine(ctx, base[0], base[1], canvas.canvasSize.width, base[1]) + canvas.drawLine(base[0], base[1], canvas.width, base[1]) inDrawDom = parseDomain(`]-inf;${this.om_0.x}[`) } else { // Low pass, constant from the beginning, linear line to the end. - canvas.drawLine(ctx, base[0], base[1], 0, base[1]) + canvas.drawLine(base[0], base[1], 0, base[1]) inDrawDom = parseDomain(`]${this.om_0.x};+inf[`) } - Function.drawFunction(canvas, ctx, dbfn, inDrawDom, Domain.R) + Function.drawFunction(canvas, dbfn, inDrawDom, Domain.R) // Dashed line representing break in function - var xpos = canvas.x2px(this.om_0.x.execute()) - var dashPxSize = 10 - for(var i = 0; i < canvas.canvasSize.height && this.omGraduation; i += dashPxSize*2) - canvas.drawLine(ctx, xpos, i, xpos, i+dashPxSize) + let xpos = canvas.x2px(this.om_0.x.execute()) + let dashPxSize = 10 + for(let i = 0; i < canvas.height && this.omGraduation; i += dashPxSize*2) + canvas.drawLine(xpos, i, xpos, i+dashPxSize) // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } update() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index 14ff351..5b32ec5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -57,6 +57,7 @@ export default class PhaseBode extends ExecutableObject { } om_0.requiredBy.push(this) } + /** @type {Point} */ this.om_0 = om_0 this.unit = unit this.labelPosition = labelPosition @@ -100,21 +101,21 @@ export default class PhaseBode extends ExecutableObject { return true } - draw(canvas, ctx) { + draw(canvas) { let baseX = canvas.x2px(this.om_0.x.execute()) let omy = this.om_0.y.execute() let augmt = this.phase.execute() let baseY = canvas.y2px(omy) let augmtY = canvas.y2px(omy+augmt) // Before change line. - canvas.drawLine(ctx, 0, baseY, Math.min(baseX, canvas.canvasSize.height), baseY) + canvas.drawLine(0, baseY, Math.min(baseX, canvas.height), baseY) // Transition line. - canvas.drawLine(ctx, baseX, baseY, baseX, augmtY) + canvas.drawLine(baseX, baseY, baseX, augmtY) // After change line - canvas.drawLine(ctx, Math.max(0, baseX), augmtY, canvas.canvasSize.width, augmtY) + canvas.drawLine(Math.max(0, baseX), augmtY, canvas.width, augmtY) // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } update() { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index d03053d..03de816 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -58,24 +58,22 @@ export default class Point extends DrawableObject { return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.pointStyle] } - draw(canvas, ctx) { - var [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())] - var pointSize = 8+(ctx.lineWidth*2) + draw(canvas) { + let [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())] + let pointSize = 8+(canvas.linewidth*2) switch(this.pointStyle) { case '●': - ctx.beginPath(); - ctx.ellipse(canvasX-pointSize/2, canvasY-pointSize/2, pointSize, pointSize) - ctx.fill(); + canvas.disc(canvasX, canvasY, pointSize/2) break; case '✕': - canvas.drawLine(ctx, canvasX-pointSize/2, canvasY-pointSize/2, canvasX+pointSize/2, canvasY+pointSize/2) - canvas.drawLine(ctx, canvasX-pointSize/2, canvasY+pointSize/2, canvasX+pointSize/2, canvasY-pointSize/2) + canvas.drawLine(canvasX-pointSize/2, canvasY-pointSize/2, canvasX+pointSize/2, canvasY+pointSize/2) + canvas.drawLine(canvasX-pointSize/2, canvasY+pointSize/2, canvasX+pointSize/2, canvasY-pointSize/2) break; case '+': - ctx.fillRect(canvasX-pointSize/2, canvasY-1, pointSize, 2) - ctx.fillRect(canvasX-1, canvasY-pointSize/2, 2, pointSize) + canvas.fillRect(canvasX-pointSize/2, canvasY-1, pointSize, 2) + canvas.fillRect(canvasX-1, canvasY-pointSize/2, 2, pointSize) break; } - this.drawLabel(canvas, ctx, this.labelPosition, canvasX, canvasY) + this.drawLabel(canvas, this.labelPosition, canvasX, canvasY) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 32105d1..0bee9a0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -92,61 +92,51 @@ export default class RepartitionFunction extends ExecutableObject { } } - draw(canvas, ctx) { + draw(canvas) { let currentY = 0; let keys = Object.keys(this.probabilities).map(idx => parseInt(idx)).sort((a,b) => a-b) if(canvas.isVisible(keys[0],this.probabilities[keys[0]].replace(/,/g, '.'))) { - canvas.drawLine(ctx, - 0, - canvas.y2px(0), - canvas.x2px(keys[0]), - canvas.y2px(0) - ) + canvas.drawLine(0, canvas.y2px(0), canvas.x2px(keys[0]), canvas.y2px(0)) if(canvas.isVisible(keys[0],0)) { - ctx.beginPath(); - ctx.arc(canvas.x2px(keys[0])+4,canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2); - ctx.stroke(); + canvas.arc(canvas.x2px(keys[0])+4,canvas.y2px(0), 4, Math.PI / 2, 3 * Math.PI / 2); } } for(let i = 0; i < keys.length-1; i++) { let idx = keys[i]; currentY += parseFloat(this.probabilities[idx].replace(/,/g, '.')); if(canvas.isVisible(idx,currentY) || canvas.isVisible(keys[i+1],currentY)) { - canvas.drawLine(ctx, + canvas.drawLine( Math.max(0,canvas.x2px(idx)), canvas.y2px(currentY), - Math.min(canvas.canvasSize.width,canvas.x2px(keys[i+1])), + Math.min(canvas.width,canvas.x2px(keys[i+1])), canvas.y2px(currentY) ) if(canvas.isVisible(idx,currentY)) { - ctx.beginPath(); - ctx.arc(canvas.x2px(idx),canvas.y2px(currentY), 4, 0, 2 * Math.PI); - ctx.fill(); + canvas.disc(canvas.x2px(idx), canvas.y2px(currentY), 4) } if(canvas.isVisible(keys[i+1],currentY)) { - ctx.beginPath(); - ctx.arc(canvas.x2px(keys[i+1])+4,canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2); - ctx.stroke(); + canvas.arc(canvas.x2px(keys[i+1])+4,canvas.y2px(currentY), 4, Math.PI / 2, 3 * Math.PI / 2); } } } if(canvas.isVisible(keys[keys.length-1],currentY+parseFloat(this.probabilities[keys[keys.length-1]]))) { - canvas.drawLine(ctx, + canvas.drawLine( Math.max(0,canvas.x2px(keys[keys.length-1])), canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))), - canvas.canvasSize.width, + canvas.width, canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))) ) - ctx.beginPath(); - ctx.arc( + canvas.disc( canvas.x2px(keys[keys.length-1]), - canvas.y2px(currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.'))), - 4, 0, 2 * Math.PI); - ctx.fill(); + canvas.y2px( + currentY+parseFloat(this.probabilities[keys[keys.length-1]].replace(/,/g, '.')) + ), + 4 + ) } // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index 4e06b56..a7af26f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -123,11 +123,11 @@ export default class Sequence extends ExecutableObject { } } - draw(canvas, ctx) { - Function.drawFunction(canvas, ctx, this.sequence, canvas.logscalex ? Domain.NE : Domain.N, Domain.R, this.drawPoints, this.drawDashedLines) + draw(canvas) { + Function.drawFunction(canvas, this.sequence, canvas.logscalex ? Domain.NE : Domain.N, Domain.R, this.drawPoints, this.drawDashedLines) // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs index e03ca81..947c99f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs @@ -89,7 +89,7 @@ export default class SommeGainsBode extends ExecutableObject { let baseY = 0 let om0xGains = {1000000000: 0} // To draw the last part let om0xPass = {1000000000: 'high'} // To draw the last part - Objects.currentObjects['Gain Bode'].forEach(function(gainObj) { // Sorting by their om_0 position. + for(/** @type {GainBode} */ let gainObj of Objects.currentObjects['Gain Bode']) { // Sorting by their om_0 position. let om0x = gainObj.om_0.x.execute() if(om0xGains[om0x] === undefined) { om0xGains[om0x] = gainObj.gain.execute() @@ -99,7 +99,7 @@ export default class SommeGainsBode extends ExecutableObject { om0xPass[om0x+0.001] = gainObj.pass === 'high' } baseY += gainObj.execute(drawMin) - }) + } // Sorting the om_0x let om0xList = Object.keys(om0xGains).map(x => parseFloat(x)) // THEY WERE CONVERTED TO STRINGS... om0xList.sort((a,b) => a - b) @@ -130,13 +130,13 @@ export default class SommeGainsBode extends ExecutableObject { } } - draw(canvas, ctx) { + draw(canvas) { if(this.cachedParts.length > 0) { for(let [dbfn, inDrawDom] of this.cachedParts) { - Function.drawFunction(canvas, ctx, dbfn, inDrawDom, Domain.R) + Function.drawFunction(canvas, dbfn, inDrawDom, Domain.R) if(inDrawDom.includes(this.labelX)) { // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs index 328c069..30ad4b0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs @@ -89,7 +89,7 @@ export default class SommePhasesBode extends ExecutableObject { if(Objects.currentObjects['Phase Bode'] !== undefined) { console.log('Recalculating cache phase') - for(let obj of Objects.currentObjects['Phase Bode']) { + for(/** @type {PhaseBode} */ let obj of Objects.currentObjects['Phase Bode']) { this.om0xList.push(obj.om_0.x.execute()) if(phasesDict[obj.om_0.x.execute()] === undefined) { phasesDict[obj.om_0.x.execute()] = obj.phase.execute() @@ -110,18 +110,18 @@ export default class SommePhasesBode extends ExecutableObject { } } - draw(canvas, ctx) { + draw(canvas) { for(let i = 0; i < this.om0xList.length-1; i++) { let om0xBegin = canvas.x2px(this.om0xList[i]) let om0xEnd = canvas.x2px(this.om0xList[i+1]) let baseY = canvas.y2px(this.phasesList[i]) let nextY = canvas.y2px(this.phasesList[i+1]) - canvas.drawLine(ctx, om0xBegin, baseY, om0xEnd, baseY) - canvas.drawLine(ctx, om0xEnd, baseY, om0xEnd, nextY) + canvas.drawLine(om0xBegin, baseY, om0xEnd, baseY) + canvas.drawLine(om0xEnd, baseY, om0xEnd, nextY) } // Label - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.labelX), canvas.y2px(this.execute(this.labelX))) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index 040e7bd..e3e2ba2 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -90,9 +90,9 @@ export default class Text extends DrawableObject { return `\\textsf{${this.latexMarkupText()}}` } - draw(canvas, ctx) { + draw(canvas) { let yOffset = this.disableLatex ? canvas.textsize-4 : 0 - this.drawLabel(canvas, ctx, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())+yOffset, this.disableLatex) + this.drawLabel(canvas, this.labelPosition, canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())+yOffset, this.disableLatex) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 036c408..236bd4a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -91,8 +91,8 @@ export default class XCursor extends DrawableObject { } getTargetValueLatexLabel() { - var t = this.targetElement - var approx = '' + let t = this.targetElement + let approx = '' if(this.approximate) { approx = t.execute(this.x.execute()) approx = approx.toPrecision(this.rounding + Math.round(approx).toString().length) @@ -142,39 +142,35 @@ export default class XCursor extends DrawableObject { } } - draw(canvas, ctx) { + draw(canvas) { let xpos = canvas.x2px(this.x.execute()) switch(this.displayStyle) { case '— — — — — — —': - var dashPxSize = 10 - for(var i = 0; i < canvas.canvasSize.height; i += dashPxSize*2) - canvas.drawLine(ctx, xpos, i, xpos, i+dashPxSize) + canvas.drawDashedLine(xpos, 0, xpos, canvas.height, 20) break; case '⸺⸺⸺⸺⸺⸺': - canvas.drawXLine(ctx, this.x.execute()) + canvas.drawXLine(this.x.execute()) break; case '• • • • • • • • • •': - var pointDistancePx = 10 - var pointSize = 2 - ctx.beginPath(); - for(var i = 0; i < canvas.canvasSize.height; i += pointDistancePx) - ctx.ellipse(xpos-pointSize/2, i-pointSize/2, pointSize, pointSize) - ctx.fill(); + let pointDistancePx = 10 + let pointSize = 2 + for(let i = 0; i < canvas.height; i += pointDistancePx) + canvas.disc(xpos, i, pointSize) break; } // Drawing label at the top of the canvas. - this.drawLabel(canvas, ctx, this.labelPosition, xpos, 0, false, null, null, - (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, 5, ltxImg.width, ltxImg.height), - (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, textSize.height+5)) + this.drawLabel(canvas, this.labelPosition, xpos, 0, false, null, null, + (x,y,ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, 5, ltxImg.width, ltxImg.height), + (x,y,text,textSize) => canvas.drawVisibleText(text, x, textSize.height+5)) // Drawing label at the position of the target element. if(this.targetValuePosition === 'Next to target' && this.targetElement != null) { let ypos = canvas.y2px(this.targetElement.execute(this.x.execute())) - this.drawLabel(canvas, ctx, this.labelPosition, xpos, ypos, false, + this.drawLabel(canvas, this.labelPosition, xpos, ypos, false, this.getTargetValueLatexLabel.bind(this), this.getTargetValueLabel.bind(this), - (x,y,ltxImg) => canvas.drawVisibleImage(ctx, ltxImg.source, x, y, ltxImg.width, ltxImg.height), - (x,y,text,textSize) => canvas.drawVisibleText(ctx, text, x, y+textSize.height)) + (x,y,ltxImg) => canvas.drawVisibleImage(ltxImg.source, x, y, ltxImg.width, ltxImg.height), + (x,y,text,textSize) => canvas.drawVisibleText(text, x, y+textSize.height)) } } } From 82e8413e56ef3360ac0359111593178aea7b56f4 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 29 Mar 2024 17:53:10 +0100 Subject: [PATCH 185/436] Creating IO JS module. --- LogarithmPlotter/i18n/lp_de.ts | 377 ++++++++++-------- LogarithmPlotter/i18n/lp_en.ts | 377 ++++++++++-------- LogarithmPlotter/i18n/lp_es.ts | 192 ++++----- LogarithmPlotter/i18n/lp_fr.ts | 377 ++++++++++-------- LogarithmPlotter/i18n/lp_hu.ts | 373 +++++++++-------- LogarithmPlotter/i18n/lp_nb_NO.ts | 233 ++++++----- LogarithmPlotter/i18n/lp_template.ts | 192 ++++----- LogarithmPlotter/logarithmplotter.py | 57 ++- .../LogarithmPlotter/LogarithmPlotter.qml | 156 ++------ .../eu/ad5001/LogarithmPlotter/Settings.qml | 10 +- .../eu/ad5001/LogarithmPlotter/js/autoload.js | 3 +- .../LogarithmPlotter/js/history/common.mjs | 3 + .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 168 ++++++++ LogarithmPlotter/util/config.py | 2 +- LogarithmPlotter/util/helper.py | 61 +-- LogarithmPlotter/util/js.py | 52 +++ LogarithmPlotter/util/latex.py | 5 +- LogarithmPlotter/util/native.py | 25 +- LogarithmPlotter/util/update.py | 33 +- 19 files changed, 1472 insertions(+), 1224 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs create mode 100644 LogarithmPlotter/util/js.py diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 2aad151..407b284 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter Über LogarithmPlotter @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Neues %1objekt erstellen - + Pick on graph Aufnehmen auf Graph @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten Name - Name + Name Label content - Etikett + Etikett null - leer + leer name - Name + Name name + value - Name + Wert + Name + Wert + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen @@ -437,64 +437,52 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter - Objects - Objekte + Objekte - Settings - Einstellungen + Einstellungen - History - Verlauf + Verlauf - Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. - Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. - Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. - Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. - Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: - Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. - Copied plot screenshot to clipboard! - Grafik in die Zwischenablage kopiert! + Grafik in die Zwischenablage kopiert! - &Update - &Aktualisieren + &Aktualisieren - &Update LogarithmPlotter - LogarithmPlotter &aktualisieren + LogarithmPlotter &aktualisieren @@ -519,23 +507,23 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen Delete %1 %2 - %1 %2 löschen + %1 %2 löschen Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen @@ -575,7 +563,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Snap to grid - Am Gitter einrasten + Am Gitter einrasten @@ -603,7 +591,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Zeigereinstellungen ausblenden - + (no pick selected) (keine Auswahl ausgewählt) @@ -816,30 +804,30 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" color %1 %2's color changed from %3 to %4. - %1 %2 wurde von %3 bis %4 umgefärbt. + %1 %2 wurde von %3 bis %4 umgefärbt. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) + Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) Note: Specify the probability for each value. - Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. + Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… + Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. + Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -858,25 +846,25 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. delete %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 of %2 changed from %3 to %4. - %1 von %2 wurde von %3 auf %4 geändert. + %1 von %2 wurde von %3 auf %4 geändert. @@ -943,11 +931,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Function definition is not permitted. - Funktionsdefinition ist nicht erlaubt. + Funktionsdefinition ist nicht erlaubt. Expected variable for assignment. - Erwartete Variable für Zuweisung. + Erwartete Variable für Zuweisung. @@ -1041,7 +1029,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. - + Error while parsing expression for property %1: %2 @@ -1052,7 +1040,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + Error while attempting to draw %1 %2: %3 @@ -1066,7 +1054,7 @@ Die letzte Änderung wurde rückgängig gemacht. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler @@ -1083,7 +1071,7 @@ Evaluated expression: %3 Ausdruck analysiert: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Fehler @@ -1092,63 +1080,126 @@ Ausdruck analysiert: %3 function Function - Funktion + Funktion Functions - Funktionen + Funktionen gainbode Bode Magnitude - Bode-Magnitude + Bode-Magnitude Bode Magnitudes - Bode-Magnituden + Bode-Magnituden low-pass - Tiefpass + Tiefpass high-pass - Hochpass + Hochpass historylib New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. Name of %1 %2 changed to %3. - Der Name von %1 %2 wurde in %3 geändert. + Der Name von %1 %2 wurde in %3 geändert. + + + + io + + + Objects + Objekte + + + + Settings + Einstellungen + + + + History + Verlauf + + + + Saved plot to '%1'. + Gespeicherte Grafik auf '%1'. + + + + Loading file '%1'. + Laden der Datei '%1'. + + + + Unknown object type: %1. + Unbekannter Objekttyp: %1. + + + + Invalid file provided. + Ungültige Datei angegeben. + + + + Could not save file: + Die Datei konnte nicht gespeichert werden: + + + + Loaded file '%1'. + Geladene Datei '%1'. + + + + Copied plot screenshot to clipboard! + Grafik in die Zwischenablage kopiert! + + + + &Update + &Aktualisieren + + + + &Update LogarithmPlotter + LogarithmPlotter &aktualisieren latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1157,12 +1208,12 @@ Wenn Sie bereits eine LaTeX-Distribution installiert haben, vergewissern Sie sic Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.org/texlive/ herunterladen. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1175,7 +1226,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1186,317 +1237,297 @@ Der Prozess '{}' brauchte zu lange, um beendet zu werden: Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - name %1 %2 renamed to %3. - %1 %2 umbenannt in %3. + %1 %2 umbenannt in %3. parameters above - ↑ Über + ↑ Über below - ↓ Unter + ↓ Unter left - ← Links + ← Links right - → Rechts + → Rechts above-left - ↖ Oben links + ↖ Oben links above-right - ↗ Oben rechts + ↗ Oben rechts below-left - ↙ Unten links + ↙ Unten links below-right - ↘ Unten rechts + ↘ Unten rechts center - >|< Zentrum + >|< Zentrum top - ↑ Über + ↑ Über bottom - ↓ Unter + ↓ Unter top-left - ↖ Oben links + ↖ Oben links top-right - ↗ Oben rechts + ↗ Oben rechts bottom-left - ↙ Unten links + ↙ Unten links bottom-right - ↘ Unten rechts + ↘ Unten rechts application - Anwendung + Anwendung function - Funktion + Funktion high - Hoch + Hoch low - Tief + Tief Next to target - Neben dem Ziel + Neben dem Ziel With label - Mit Etikett + Mit Etikett Hidden - Versteckt + Versteckt phasebode Bode Phase - Bode-Phase + Bode-Phase Bode Phases - Bode-Phasen + Bode-Phasen point Point - Punkt + Punkt Points - Punkte + Punkte position Position of %1 %2 set from "%3" to "%4". - %1 %2 wurde von "%3" nach "%4" verschoben. + %1 %2 wurde von "%3" nach "%4" verschoben. Position of %1 set from %2 to %3. - %1 wurde von %2 nach %3 verschoben. + %1 wurde von %2 nach %3 verschoben. prop expression - Ausdruck + Ausdruck definitionDomain - Definitionsbereich + Definitionsbereich destinationDomain - Reichweite + Reichweite labelPosition - Position des Etiketts + Position des Etiketts displayMode - Anzeigemodus + Anzeigemodus labelX - X-Position des Etiketts + X-Position des Etiketts drawPoints - Unentschiedene Punkte + Unentschiedene Punkte drawDashedLines - Gestrichelte Linien anzeigen + Gestrichelte Linien anzeigen om_0 - ω₀ + ω₀ pass - Pass + Pass gain - Größenordnung + Größenordnung omGraduation - Teilung auf ω zeigen + Teilung auf ω zeigen phase - Phase + Phase unit - Einheit + Einheit x - X + X y - Y + Y pointStyle - Punkt-Stil + Punkt-Stil probabilities - Wahrscheinlichkeiten + Wahrscheinlichkeiten text - Inhalt + Inhalt disableLatex - LaTeX-Rendering für diesen Text deaktivieren + LaTeX-Rendering für diesen Text deaktivieren targetElement - Zielobjekt + Zielobjekt approximate - Ungefähren Wert anzeigen + Ungefähren Wert anzeigen rounding - Rundung + Rundung displayStyle - Stil + Stil targetValuePosition - Wertposition des Ziels + Wertposition des Ziels defaultExpression - Standardausdruck + Standardausdruck baseValues - Initialisierungswerte + Initialisierungswerte color - Farbe + Farbe repartition Repartition - Verteilungsfunktion + Verteilungsfunktion Repartition functions - Verteilungsfunktionen + Verteilungsfunktionen sequence Sequence - Folge + Folge Sequences - Folgen + Folgen sommegainsbode Bode Magnitudes Sum - Bode-Magnituden Summe + Bode-Magnituden Summe sommephasesbode Bode Phases Sum - Bode-Phasen Summe + Bode-Phasen Summe text Text - Text + Text Texts - Texte + Texte @@ -1507,7 +1538,7 @@ File does not exist. Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. @@ -1525,37 +1556,37 @@ File does not exist. usage - - + + Usage: %1 Verwendung: %1 - - - + + + Usage: %1 or %2 Verwendung: %1 oder %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<von: Zahl>, <bis: Zahl>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<von: Zahl>, <bis: Zahl>, <f: String>, <Variablen: String>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: Zahl>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: String>, <Variablen: String>, <x: Zahl>) @@ -1564,22 +1595,22 @@ File does not exist. visibility %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. xcursor X Cursor - X Zeiger + X Zeiger X Cursors - X Zeiger + X Zeiger diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 591e2c2..f700aa6 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter About LogarithmPlotter @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Create new %1 - + Pick on graph Pick on graph @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 Name - Name + Name Label content - Label content + Label content null - null + null name - name + name name + value - name + value + name + value + Create new %1 - + Create new %1 + + Create new %1 @@ -437,64 +437,52 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter - Objects - Objects + Objects - Settings - Settings + Settings - History - History + History - Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. - Loading file '%1'. - Loading file '%1'. + Loading file '%1'. - Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. - Invalid file provided. - Invalid file provided. + Invalid file provided. - Could not save file: - Could not save file: + Could not save file: - Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. - Copied plot screenshot to clipboard! - Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! - &Update - &Update + &Update - &Update LogarithmPlotter - &Update LogarithmPlotter + &Update LogarithmPlotter @@ -519,23 +507,23 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - Hide %1 %2 + Hide %1 %2 Show %1 %2 - Show %1 %2 + Show %1 %2 Set %1 %2 position - Set %1 %2 position + Set %1 %2 position Delete %1 %2 - Delete %1 %2 + Delete %1 %2 Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 @@ -575,7 +563,7 @@ These settings can be changed at any time from the "Settings" menu. Snap to grid - Snap to grid + Snap to grid @@ -603,7 +591,7 @@ These settings can be changed at any time from the "Settings" menu.Hide picker settings - + (no pick selected) (no pick selected) @@ -816,30 +804,30 @@ These settings can be changed at any time from the "Settings" menu.color %1 %2's color changed from %3 to %4. - %1 %2's color changed from %3 to %4. + %1 %2's color changed from %3 to %4. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) + The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) Note: Specify the probability for each value. - Note: Specify the probability for each value. + Note: Specify the probability for each value. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - If you have latex enabled, you can use use latex markup in between $$ to create equations. + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -858,25 +846,25 @@ These settings can be changed at any time from the "Settings" menu.create New %1 %2 created. - New %1 %2 created. + New %1 %2 created. delete %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 changed from %3 to %4. - %1 of %2 changed from %3 to %4. + %1 of %2 changed from %3 to %4. @@ -943,11 +931,11 @@ These settings can be changed at any time from the "Settings" menu. Function definition is not permitted. - Function definition is not permitted. + Function definition is not permitted. Expected variable for assignment. - Expected variable for assignment. + Expected variable for assignment. @@ -1041,7 +1029,7 @@ These settings can be changed at any time from the "Settings" menu.Circular dependency detected. Objects %1 depend on %2. - + Error while parsing expression for property %1: %2 @@ -1052,7 +1040,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1066,7 +1054,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error @@ -1083,7 +1071,7 @@ Evaluated expression: %3 Evaluated expression: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Drawing error @@ -1092,63 +1080,126 @@ Evaluated expression: %3 function Function - Function + Function Functions - Functions + Functions gainbode Bode Magnitude - Bode Magnitude + Bode Magnitude Bode Magnitudes - Bode Magnitudes + Bode Magnitudes low-pass - low-pass + low-pass high-pass - high-pass + high-pass historylib New %1 %2 created. - New %1 %2 created. + New %1 %2 created. %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. Name of %1 %2 changed to %3. - Name of %1 %2 changed to %3. + Name of %1 %2 changed to %3. + + + + io + + + Objects + Objects + + + + Settings + Settings + + + + History + History + + + + Saved plot to '%1'. + Saved plot to '%1'. + + + + Loading file '%1'. + Loading file '%1'. + + + + Unknown object type: %1. + Unknown object type: %1. + + + + Invalid file provided. + Invalid file provided. + + + + Could not save file: + Could not save file: + + + + Loaded file '%1'. + Loaded file '%1'. + + + + Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! + + + + &Update + &Update + + + + &Update LogarithmPlotter + &Update LogarithmPlotter latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1157,12 +1208,12 @@ If you already have a LaTeX distribution installed, make sure it's installe Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1175,7 +1226,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1186,317 +1237,297 @@ Process '{}' took too long to finish: Please make sure your LaTeX installation is correct and report a bug if so. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - name %1 %2 renamed to %3. - %1 %2 renamed to %3. + %1 %2 renamed to %3. parameters above - ↑ Above + ↑ Above below - ↓ Below + ↓ Below left - ← Left + ← Left right - → Right + → Right above-left - ↖ Above left + ↖ Above left above-right - ↗ Above right + ↗ Above right below-left - ↙ Below left + ↙ Below left below-right - ↘ Below right + ↘ Below right center - >|< Center + >|< Center top - ↑ Top + ↑ Top bottom - ↓ Bottom + ↓ Bottom top-left - ↖ Top left + ↖ Top left top-right - ↗ Top right + ↗ Top right bottom-left - ↙ Bottom left + ↙ Bottom left bottom-right - ↘ Bottom right + ↘ Bottom right application - Application + Application function - Function + Function high - High + High low - Low + Low Next to target - Next to target + Next to target With label - With label + With label Hidden - Hidden + Hidden phasebode Bode Phase - Bode Phase + Bode Phase Bode Phases - Bode Phases + Bode Phases point Point - Point + Point Points - Points + Points position Position of %1 %2 set from "%3" to "%4". - %1 %2 moved from "%3" to "%4". + %1 %2 moved from "%3" to "%4". Position of %1 set from %2 to %3. - %1 moved from %2 to %3. + %1 moved from %2 to %3. prop expression - Expression + Expression definitionDomain - Domain + Domain destinationDomain - Range + Range labelPosition - Label position + Label position displayMode - Display mode + Display mode labelX - Label's X position + Label's X position drawPoints - Show points + Show points drawDashedLines - Show dashed lines + Show dashed lines om_0 - ω₀ + ω₀ pass - Pass + Pass gain - Magnitude gain + Magnitude gain omGraduation - Show graduation on ω₀ + Show graduation on ω₀ phase - Phase + Phase unit - Unit to use + Unit to use x - X + X y - Y + Y pointStyle - Point style + Point style probabilities - Probabilities list + Probabilities list text - Content + Content disableLatex - Disable LaTeX rendering for this text + Disable LaTeX rendering for this text targetElement - Object to target + Object to target approximate - Show approximate value + Show approximate value rounding - Rounding + Rounding displayStyle - Display style + Display style targetValuePosition - Target's value position + Target's value position defaultExpression - Default expression + Default expression baseValues - Initialisation values + Initialisation values color - Color + Color repartition Repartition - Distribution + Distribution Repartition functions - Distribution functions + Distribution functions sequence Sequence - Sequence + Sequence Sequences - Sequences + Sequences sommegainsbode Bode Magnitudes Sum - Bode Magnitudes Sum + Bode Magnitudes Sum sommephasesbode Bode Phases Sum - Bode Phases Sum + Bode Phases Sum text Text - Text + Text Texts - Texts + Texts @@ -1507,7 +1538,7 @@ File does not exist. An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. @@ -1525,37 +1556,37 @@ File does not exist. usage - - + + Usage: %1 Usage: %1 - - - + + + Usage: %1 or %2 Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f: string>, <variable: string>, <x: number>) @@ -1564,22 +1595,22 @@ File does not exist. visibility %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. xcursor X Cursor - X Cursor + X Cursor X Cursors - X Cursors + X Cursors diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index a9a0f09..c8f4310 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -402,69 +402,6 @@ These settings can be changed at any time from the "Settings" menu. - - LogarithmPlotter - - - Objects - - - - - Settings - - - - - History - - - - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not save file: - - - - - Loaded file '%1'. - - - - - Copied plot screenshot to clipboard! - - - - - &Update - - - - - &Update LogarithmPlotter - - - ObjectCreationGrid @@ -547,7 +484,7 @@ These settings can be changed at any time from the "Settings" menu. - + (no pick selected) @@ -922,7 +859,7 @@ These settings can be changed at any time from the "Settings" menu. - + Error while parsing expression for property %1: %2 @@ -930,7 +867,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -941,7 +878,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -955,27 +892,90 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error + + io + + + Objects + + + + + Settings + + + + + History + + + + + Saved plot to '%1'. + + + + + Loading file '%1'. + + + + + Unknown object type: %1. + + + + + Invalid file provided. + + + + + Could not save file: + + + + + Loaded file '%1'. + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter + + + latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -984,7 +984,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -992,26 +992,6 @@ Please make sure your latex installation is correct and report a bug if so. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - update @@ -1020,7 +1000,7 @@ File does not exist. - + No update available. @@ -1038,36 +1018,36 @@ File does not exist. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 68b0f1a..d1c0f95 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter @@ -203,13 +203,13 @@ CustomPropertyList - - + + + Create new %1 + Créer un nouvel objet %1 - + Pick on graph Prendre la position sur le graphe @@ -261,32 +261,32 @@ EditorDialog Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 Name - Nom + Nom Label content - Étiquette + Étiquette null - vide + vide name - nom + nom name + value - nom + valeur + nom + valeur + Create new %1 Traduction non litéralle pour éviter les problèmes de genre. - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 @@ -445,64 +445,52 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter - Objects - Objets + Objets - Settings - Paramètres + Paramètres - History - Historique + Historique - Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. - Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. - Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. - Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. - Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : - Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. - Copied plot screenshot to clipboard! - Image du graphe copiée dans le presse-papiers ! + Image du graphe copiée dans le presse-papiers ! - &Update - &Mise à jour + &Mise à jour - &Update LogarithmPlotter - &Mettre à jour LogarithmPlotter + &Mettre à jour LogarithmPlotter @@ -527,23 +515,23 @@ These settings can always be changed at any time from the "Settings" m Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 @@ -583,7 +571,7 @@ These settings can always be changed at any time from the "Settings" m Snap to grid - Placement sur la grille + Placement sur la grille @@ -611,7 +599,7 @@ These settings can always be changed at any time from the "Settings" m Cacher les paramètres du pointeur - + (no pick selected) (aucun axe sélectionné) @@ -824,31 +812,31 @@ These settings can always be changed at any time from the "Settings" m color %1 %2's color changed from %3 to %4. - %1 %2 a été re colorisé du %3 au %4. + %1 %2 a été re colorisé du %3 au %4. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) + Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) Note: Specify the probability for each value. - Note : Spécifiez la probabilité pour chaque valeur. + Note : Spécifiez la probabilité pour chaque valeur. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... - Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… + Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. + Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -867,25 +855,25 @@ These settings can always be changed at any time from the "Settings" m create New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. delete %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 of %2 changed from %3 to %4. - %1 de %2 modifiée de %3 à %4. + %1 de %2 modifiée de %3 à %4. @@ -952,11 +940,11 @@ These settings can always be changed at any time from the "Settings" m Function definition is not permitted. - La définition de fonctions n'est pas autorisée. + La définition de fonctions n'est pas autorisée. Expected variable for assignment. - Une variable est attendue pour l'affectation. + Une variable est attendue pour l'affectation. @@ -1050,7 +1038,7 @@ These settings can always be changed at any time from the "Settings" m Dépendance circulaire détectée. Les objets %1 dépendent de %2. - + Error while parsing expression for property %1: %2 @@ -1061,7 +1049,7 @@ Evaluated expression: %3 Formule analysée : %3 - + Error while attempting to draw %1 %2: %3 @@ -1075,7 +1063,7 @@ La dernière modification a été annulée. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe @@ -1092,7 +1080,7 @@ Evaluated expression: %3 Formule analysée : %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Erreur @@ -1101,63 +1089,126 @@ Formule analysée : %3 function Function - Fonction + Fonction Functions - Fonctions + Fonctions gainbode Bode Magnitude - Gain de Bode + Gain de Bode Bode Magnitudes - Gains de Bode + Gains de Bode low-pass - passe-bas + passe-bas high-pass - passe-haut + passe-haut historylib New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). Name of %1 %2 changed to %3. - Le nom de %1 %2 a été changé en %3. + Le nom de %1 %2 a été changé en %3. + + + + io + + + Objects + Objets + + + + Settings + Paramètres + + + + History + Historique + + + + Saved plot to '%1'. + Graphe sauvegardé dans '%1'. + + + + Loading file '%1'. + Chargement du fichier '%1'. + + + + Unknown object type: %1. + Type d'objet inconnu : %1. + + + + Invalid file provided. + Fichier fourni invalide. + + + + Could not save file: + Impossible de sauvegarder le fichier : + + + + Loaded file '%1'. + Fichier '%1' chargé. + + + + Copied plot screenshot to clipboard! + Image du graphe copiée dans le presse-papiers ! + + + + &Update + &Mise à jour + + + + &Update LogarithmPlotter + &Mettre à jour LogarithmPlotter latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1166,12 +1217,12 @@ Si vous avez déjà installé une distribution LaTeX, assurez-vous qu'elle Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l'adresse https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1184,7 +1235,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1195,317 +1246,297 @@ Le processus '{}' a mis trop de temps à se terminer : Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - name %1 %2 renamed to %3. - %1 %2 renommé(e) en %3. + %1 %2 renommé(e) en %3. parameters above - ↑ Au dessus + ↑ Au dessus below - ↓ En dessous + ↓ En dessous left - ← À gauche + ← À gauche right - → À droite + → À droite above-left - ↖ Au dessus à gauche + ↖ Au dessus à gauche above-right - ↗ Au dessus à droite + ↗ Au dessus à droite below-left - ↙ En dessous à gauche + ↙ En dessous à gauche below-right - ↘ En dessous à droite + ↘ En dessous à droite center - >|< Centré + >|< Centré top - ↑ Au dessus + ↑ Au dessus bottom - ↓ En dessous + ↓ En dessous top-left - ↖ Au dessus à gauche + ↖ Au dessus à gauche top-right - ↗ Au dessus à droite + ↗ Au dessus à droite bottom-left - ↙ En dessous à gauche + ↙ En dessous à gauche bottom-right - ↘ En dessous à droite + ↘ En dessous à droite application - Application + Application function - Fonction + Fonction high - Haut + Haut low - Bas + Bas Next to target - A côté de la cible + A côté de la cible With label - Avec l'étiquette + Avec l'étiquette Hidden - Caché + Caché phasebode Bode Phase - Phase de Bode + Phase de Bode Bode Phases - Phases de Bode + Phases de Bode point Point - Point + Point Points - Points + Points position Position of %1 %2 set from "%3" to "%4". - %1 %2 a été déplacé depuis "%3" vers "%4". + %1 %2 a été déplacé depuis "%3" vers "%4". Position of %1 set from %2 to %3. - %1 a été déplacé depuis %2 vers %3. + %1 a été déplacé depuis %2 vers %3. prop expression - Expression + Expression definitionDomain - Domaine de définition + Domaine de définition destinationDomain - Portée + Portée labelPosition - Position de l'étiquette + Position de l'étiquette displayMode - Mode d'affichage + Mode d'affichage labelX - Position en X de l'étiquette + Position en X de l'étiquette drawPoints - Afficher les points + Afficher les points drawDashedLines - Afficher les pointillés + Afficher les pointillés om_0 - ω₀ + ω₀ pass - Passe + Passe gain - Gain + Gain omGraduation - Afficher la graduation sur ω₀ + Afficher la graduation sur ω₀ phase - Phase + Phase unit - Unité de la phase + Unité de la phase x - X + X y - Y + Y pointStyle - Style du point + Style du point probabilities - Liste de probabilités + Liste de probabilités text - Contenu + Contenu disableLatex - Désactiver le rendu LaTeX pour ce texte + Désactiver le rendu LaTeX pour ce texte targetElement - Objet à cibler + Objet à cibler approximate - Afficher la valeur approximative + Afficher la valeur approximative rounding - Arrondi + Arrondi displayStyle - Style d'affichage + Style d'affichage targetValuePosition - Position de la valeur de la cible + Position de la valeur de la cible defaultExpression - Expression + Expression baseValues - Valeurs d'initialisation + Valeurs d'initialisation color - Couleur + Couleur repartition Repartition - Répartition + Répartition Repartition functions - Fonctions de répartition + Fonctions de répartition sequence Sequence - Suite + Suite Sequences - Suites + Suites sommegainsbode Bode Magnitudes Sum - Sommes des gains de Bode + Sommes des gains de Bode sommephasesbode Bode Phases Sum - Somme des phases de Bode + Somme des phases de Bode text Text - Texte + Texte Texts - Textes + Textes @@ -1516,7 +1547,7 @@ File does not exist. Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. @@ -1534,37 +1565,37 @@ File does not exist. usage - - + + Usage: %1 Emploi : %1 - - - + + + Usage: %1 or %2 Emploi : %1 ou %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integral(<de : nombre>, <à : nombre>, <f : Objet exécutable>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integral(<de : nombre>, <à : nombre>, <f : fonction chaîne>, <variable>) - + derivative(<f: ExecutableObject>, <x: number>) derivative(<f : Objet exécutable>, <x : nombre>) - + derivative(<f: string>, <variable: string>, <x: number>) derivative(<f : fonction chaîne>, <variable>, <x : nombre>) @@ -1573,22 +1604,22 @@ File does not exist. visibility %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). xcursor X Cursor - Curseur X + Curseur X X Cursors - Curseurs X + Curseurs X diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 5a311df..9222b65 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Új %1 létrehozása - + Pick on graph Ábra kijelölése @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése Name - Név + Név Label content - Címke tartalom + Címke tartalom null - üres + üres name - név + név name + value - név + érték + név + érték + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása @@ -437,64 +437,52 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter - Objects - Tárgyak + Tárgyak - Settings - Beállítások + Beállítások - History - Előzmények + Előzmények - Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. - Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. - Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. - Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. - Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: - Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. - Copied plot screenshot to clipboard! - Ábra képernyőkép vágólapra másolva! + Ábra képernyőkép vágólapra másolva! - &Update - &Frissítés + &Frissítés - &Update LogarithmPlotter - A LogarithmPlotter &frissítése + A LogarithmPlotter &frissítése @@ -519,23 +507,23 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása Delete %1 %2 - %1 %2 törlése + %1 %2 törlése Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 @@ -575,7 +563,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Snap to grid - Rácshoz illesztés + Rácshoz illesztés @@ -603,7 +591,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Kijelölési beállítások elrejtése - + (no pick selected) (nincs kijelölés kiválasztva) @@ -816,30 +804,30 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. color %1 %2's color changed from %3 to %4. - %1 %2 színe %3-ról %4-re változott. + %1 %2 színe %3-ról %4-re változott. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) + A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) Note: Specify the probability for each value. - Megjegyzés: Adja meg az egyes értékek valószínűségét. + Megjegyzés: Adja meg az egyes értékek valószínűségét. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … + Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … If you have latex enabled, you can use use latex markup in between $$ to create equations. - Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. + Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -858,25 +846,25 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. delete %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 of %2 changed from %3 to %4. - %1/%2 megváltozott. Régi érték: %3, új érték: %4. + %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -943,11 +931,11 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Function definition is not permitted. - A függvény meghatározása nem engedélyezett. + A függvény meghatározása nem engedélyezett. Expected variable for assignment. - A hozzárendeléshez várt változó. + A hozzárendeléshez várt változó. @@ -1041,7 +1029,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. - + Error while parsing expression for property %1: %2 @@ -1052,7 +1040,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + Error while attempting to draw %1 %2: %3 @@ -1066,7 +1054,7 @@ Az utolsó módosítás visszavonása. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba @@ -1083,7 +1071,7 @@ Evaluated expression: %3 Kiértékelt kifejezés: %3 - + LogarithmPlotter - Drawing error LogarithmPlotter - Rajzolási hiba @@ -1092,59 +1080,122 @@ Kiértékelt kifejezés: %3 function Function - Függvény + Függvény Functions - Függvények + Függvények gainbode Bode Magnitude - Bode-nagyságrend + Bode-nagyságrend Bode Magnitudes - Bode-nagyságrendek + Bode-nagyságrendek low-pass - aluláteresztő + aluláteresztő high-pass - felüláteresztő + felüláteresztő historylib New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. + + + + io + + + Objects + + + + + Settings + Beállítások + + + + History + Előzmények + + + + Saved plot to '%1'. + Ábra mentve ide: „%1”. + + + + Loading file '%1'. + A(z) „%1” fájl betöltése folyamatban van. + + + + Unknown object type: %1. + Ismeretlen objektumtípus: %1. + + + + Invalid file provided. + A megadott fájl érvénytelen. + + + + Could not save file: + A fájl mentése nem sikerült: + + + + Loaded file '%1'. + A(z) „%1” fájl betöltve. + + + + Copied plot screenshot to clipboard! + Ábra képernyőkép vágólapra másolva! + + + + &Update + &Frissítés + + + + &Update LogarithmPlotter + A LogarithmPlotter &frissítése latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. @@ -1153,12 +1204,12 @@ Ha már telepítve van egy LaTeX disztribúció, győződjön meg arról, hogy a Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https://tug.org/texlive/ címről. - + DVIPNG was not found. Make sure you include it from your Latex distribution. DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1171,7 +1222,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1182,313 +1233,293 @@ A(z) „{}” folyamat túl sokáig tartott a befejezéshez: Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - name %1 %2 renamed to %3. - %1 %2 átnevezve erre: %3. + %1 %2 átnevezve erre: %3. parameters above - ↑ Felett + ↑ Felett below - ↓ Alatt + ↓ Alatt left - ← Balra + ← Balra right - → Jobbra + → Jobbra above-left - ↖ Felett, balra + ↖ Felett, balra above-right - ↗ Felett, jobbra + ↗ Felett, jobbra below-left - ↙ Alatt, balra + ↙ Alatt, balra below-right - ↘ Alatt, jobbra + ↘ Alatt, jobbra center - >|< Középre + >|< Középre top - ↑ Felső + ↑ Felső bottom - ↓ Alsó + ↓ Alsó top-left - ↖ Bal felső + ↖ Bal felső top-right - ↗ Jobb felső + ↗ Jobb felső bottom-left - ↙ Bal alsó + ↙ Bal alsó bottom-right - ↘ Jobb alsó + ↘ Jobb alsó application - Alkalmazás + Alkalmazás function - Függvény + Függvény high - Magas + Magas low - Alul + Alul Next to target - Cél mellé + Cél mellé With label - Címkével + Címkével Hidden - Rejtett + Rejtett phasebode Bode Phase - Bode-fázis + Bode-fázis Bode Phases - Bode-fázisok + Bode-fázisok point Point - Pont + Pont Points - Pontok + Pontok position Position of %1 %2 set from "%3" to "%4". - %1 %2 áthelyezve innen: „%3” ide: „%4”. + %1 %2 áthelyezve innen: „%3” ide: „%4”. Position of %1 set from %2 to %3. - %1 áthelyezve innen: %2 ide: %3. + %1 áthelyezve innen: %2 ide: %3. prop expression - Kifejezés + Kifejezés definitionDomain - Abszcissza tartomány + Abszcissza tartomány destinationDomain - Ordináta tartomány + Ordináta tartomány labelPosition - Címke helyzete + Címke helyzete displayMode - Megjelenítési mód + Megjelenítési mód labelX - Címke X helyzete + Címke X helyzete drawPoints - Pontok megjelenítése + Pontok megjelenítése drawDashedLines - Szaggatott vonalak megjelenítése + Szaggatott vonalak megjelenítése om_0 - ω₀ + ω₀ pass - Áteresztő + Áteresztő gain - Nagyságrend nyeresége + Nagyságrend nyeresége omGraduation - ω₀ érettségi megjelenítése + ω₀ érettségi megjelenítése phase - Fázis + Fázis unit - Egység használata + Egység használata x - X + X y - Y + Y pointStyle - Pontstílus + Pontstílus probabilities - Valószínűségek listája + Valószínűségek listája text - Tartalom + Tartalom disableLatex - LaTeX-megjelenítés letiltása ennél a szövegnél + LaTeX-megjelenítés letiltása ennél a szövegnél targetElement - Tárgycél + Tárgycél approximate - Hozzávetőleges érték megjelenítése + Hozzávetőleges érték megjelenítése rounding - Kerekítés + Kerekítés displayStyle - Megjelenítési stílus + Megjelenítési stílus targetValuePosition - Cél értékpozíciója + Cél értékpozíciója defaultExpression - Alapértelmezett kifejezés + Alapértelmezett kifejezés baseValues - Kezdeményezési értékek + Kezdeményezési értékek repartition Repartition - Elosztás + Elosztás Repartition functions - Elosztási függvények + Elosztási függvények sequence Sequence - Sorozat + Sorozat Sequences - Sorozatok + Sorozatok sommegainsbode Bode Magnitudes Sum - Bode-nagyságrendek összege + Bode-nagyságrendek összege sommephasesbode Bode Phases Sum - Bode-fázisok összege + Bode-fázisok összege text Text - Szöveg + Szöveg Texts - Szövegek + Szövegek @@ -1499,7 +1530,7 @@ File does not exist. Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. @@ -1517,37 +1548,37 @@ File does not exist. usage - - + + Usage: %1 Használat: %1 - - - + + + Usage: %1 or %2 Használat: %1 vagy %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: végrehajtható objektum>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) integrál(<alsó korlát: szám>, <felső korlát: szám>, <függvény: karakterlánc>, <változó: karakterlánc>) - + derivative(<f: ExecutableObject>, <x: number>) derivált(<függvény: VégrehajthatóObjektum>, <x: szám>) - + derivative(<f: string>, <variable: string>, <x: number>) derivált(<függvény: karakterlánc>, <változó: karakterlánc>, <x: szám>) @@ -1556,22 +1587,22 @@ File does not exist. visibility %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. xcursor X Cursor - X kurzor + X kurzor X Cursors - X kurzorok + X kurzorok diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 98fa6fb..faeb53b 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter Om @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 + Opprett nytt %1 - + Pick on graph @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 @@ -437,64 +437,52 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. LogarithmPlotter - Objects - Objekter + Objekter - Settings - Innstillinger + Innstillinger - History - Historikk + Historikk - Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». - Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. - Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. - Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. - Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: - Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». - Copied plot screenshot to clipboard! - Kopierte plott-skjermavbildning til utklippstavlen! + Kopierte plott-skjermavbildning til utklippstavlen! - &Update - &Oppdater + &Oppdater - &Update LogarithmPlotter - &Installer ny versjon av LogartimePlotter + &Installer ny versjon av LogartimePlotter @@ -519,11 +507,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position @@ -531,11 +519,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 @@ -575,7 +563,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Snap to grid - Fest til rutenett + Fest til rutenett @@ -603,7 +591,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + (no pick selected) @@ -999,7 +987,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + Error while parsing expression for property %1: %2 @@ -1007,7 +995,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -1018,7 +1006,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -1032,7 +1020,7 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error @@ -1041,71 +1029,134 @@ Evaluated expression: %3 function Function - Funksjon + Funksjon Functions - Funksjoner + Funksjoner gainbode Bode Magnitude - Bode-magnitude + Bode-magnitude Bode Magnitudes - Bode-magnituder + Bode-magnituder low-pass - lavpass + lavpass high-pass - høypass + høypass historylib New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». %1 %2 shown. - %1 %2 vist. + %1 %2 vist. %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. + + + + io + + + Objects + Objekter + + + + Settings + Innstillinger + + + + History + Historikk + + + + Saved plot to '%1'. + Lagret plott i «%1». + + + + Loading file '%1'. + Laster inn «%1»-fil. + + + + Unknown object type: %1. + Ukjent objekttype: %1. + + + + Invalid file provided. + Ugyldig fil angitt. + + + + Could not save file: + Kunne ikke lagre fil: + + + + Loaded file '%1'. + Lastet inn filen «%1». + + + + Copied plot screenshot to clipboard! + Kopierte plott-skjermavbildning til utklippstavlen! + + + + &Update + &Oppdater + + + + &Update LogarithmPlotter + &Installer ny versjon av LogartimePlotter latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1114,7 +1165,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1122,64 +1173,44 @@ Please make sure your latex installation is correct and report a bug if so. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - phasebode Bode Phase - Bode-fase + Bode-fase Bode Phases - Bode-faser + Bode-faser point Point - Punkt + Punkt Points - Punkter + Punkter repartition Repartition - Distribusjon + Distribusjon Repartition functions - Distribusjonsfunksjoner + Distribusjonsfunksjoner sequence Sequence - Følge + Følge Sequences @@ -1190,25 +1221,25 @@ File does not exist. sommegainsbode Bode Magnitudes Sum - Bode-magnitudesum + Bode-magnitudesum sommephasesbode Bode Phases Sum - Bode-fasesum + Bode-fasesum text Text - Tekst + Tekst Texts - Tekster + Tekster @@ -1219,7 +1250,7 @@ File does not exist. En ny versjon av LogartimePlotter (v{}) er tilgjengelig - + No update available. Ingen nye versjoner. @@ -1237,36 +1268,36 @@ File does not exist. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index b88fc2e..3e4a80b 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -4,8 +4,8 @@ About - + About LogarithmPlotter @@ -202,13 +202,13 @@ CustomPropertyList - - + + + Create new %1 - + Pick on graph @@ -402,69 +402,6 @@ These settings can be changed at any time from the "Settings" menu. - - LogarithmPlotter - - - Objects - - - - - Settings - - - - - History - - - - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not save file: - - - - - Loaded file '%1'. - - - - - Copied plot screenshot to clipboard! - - - - - &Update - - - - - &Update LogarithmPlotter - - - ObjectCreationGrid @@ -547,7 +484,7 @@ These settings can be changed at any time from the "Settings" menu. - + (no pick selected) @@ -922,7 +859,7 @@ These settings can be changed at any time from the "Settings" menu. - + Error while parsing expression for property %1: %2 @@ -930,7 +867,7 @@ Evaluated expression: %3 - + Error while attempting to draw %1 %2: %3 @@ -941,7 +878,7 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error @@ -955,27 +892,90 @@ Evaluated expression: %3 - + LogarithmPlotter - Drawing error + + io + + + Objects + + + + + Settings + + + + + History + + + + + Saved plot to '%1'. + + + + + Loading file '%1'. + + + + + Unknown object type: %1. + + + + + Invalid file provided. + + + + + Could not save file: + + + + + Loaded file '%1'. + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter + + + latex - + No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -984,7 +984,7 @@ Please make sure your latex installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -992,26 +992,6 @@ Please make sure your latex installation is correct and report a bug if so. - - main - - - Could not open file "{}": -{} - - - - - Could not open file: "{}" -File does not exist. - - - - - Built with PySide6 (Qt) v{} and python v{} - - - update @@ -1020,7 +1000,7 @@ File does not exist. - + No update available. @@ -1038,36 +1018,36 @@ File does not exist. usage - - + + Usage: %1 - - - + + + Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) diff --git a/LogarithmPlotter/logarithmplotter.py b/LogarithmPlotter/logarithmplotter.py index 5270534..d4fd4aa 100644 --- a/LogarithmPlotter/logarithmplotter.py +++ b/LogarithmPlotter/logarithmplotter.py @@ -41,15 +41,16 @@ chdir(path.dirname(path.realpath(__file__))) if path.realpath(path.join(getcwd(), "..")) not in sys_path: sys_path.append(path.realpath(path.join(getcwd(), ".."))) - from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config, native from LogarithmPlotter.util.update import check_for_updates from LogarithmPlotter.util.helper import Helper from LogarithmPlotter.util.latex import Latex +from LogarithmPlotter.util.js import PyJSValue config.init() + def get_linux_theme(): des = { "KDE": "Fusion", @@ -62,9 +63,9 @@ def get_linux_theme(): else: # Android return "Material" - + + def run(): - if not 'QT_QUICK_CONTROLS_STYLE' in environ: environ["QT_QUICK_CONTROLS_STYLE"] = { "linux": get_linux_theme(), @@ -73,9 +74,9 @@ def run(): "cygwin": "Fusion", "darwin": "macOS" }[platform] - + dep_time = time() - print("Loaded dependencies in " + str((dep_time - start_time)*1000) + "ms.") + print("Loaded dependencies in " + str((dep_time - start_time) * 1000) + "ms.") icon_fallbacks = QIcon.fallbackSearchPaths(); base_icon_path = path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "icons") @@ -85,47 +86,45 @@ def run(): icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings"))) icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom"))) QIcon.setFallbackSearchPaths(icon_fallbacks); - - QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) + + QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(argv) app.setApplicationName("LogarithmPlotter") app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop") app.setOrganizationName("Ad5001") app.styleHints().setShowShortcutsInContextMenus(True) app.setWindowIcon(QIcon(path.realpath(path.join(getcwd(), "logarithmplotter.svg")))) - + # Installing translators translator = QTranslator() # Check if lang is forced. - forcedlang = [p for p in argv if p[:7]=="--lang="] + forcedlang = [p for p in argv if p[:7] == "--lang="] locale = QLocale(forcedlang[0][7:]) if len(forcedlang) > 0 else QLocale() - if (translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n")))): + if translator.load(locale, "lp", "_", path.realpath(path.join(getcwd(), "i18n"))): app.installTranslator(translator); - + # Installing macOS file handler. macOSFileOpenHandler = None if platform == "darwin": macOSFileOpenHandler = native.MacOSFileOpenHandler() app.installEventFilter(macOSFileOpenHandler) - + engine = QQmlApplicationEngine() global tmpfile helper = Helper(pwd, tmpfile) latex = Latex(tempdir) - modules = engine.newObject() - engine.globalObject().setProperty('Modules', modules) - engine.globalObject().setProperty('Helper', engine.newQObject(helper)) - engine.globalObject().setProperty("Latex", engine.newQObject(latex)) - # engine.rootContext().setContextProperty("Helper", helper) - # engine.rootContext().setContextProperty("Latex", latex) + js_globals = PyJSValue(engine.globalObject()) + js_globals.Modules = engine.newObject() + js_globals.Helper = engine.newQObject(helper) + js_globals.Latex = engine.newQObject(latex) engine.rootContext().setContextProperty("TestBuild", "--test-build" in argv) engine.rootContext().setContextProperty("StartTime", dep_time) - - app.translate("About","About LogarithmPlotter") # FOR SOME REASON, if this isn't included, Qt refuses to load the QML file. + + app.translate("About", "About LogarithmPlotter") + # FOR SOME REASON, if this isn't included, Qt refuses to load the QML file. engine.addImportPath(path.realpath(path.join(getcwd(), "qml"))) engine.load(path.realpath(path.join(getcwd(), "qml", "eu", "ad5001", "LogarithmPlotter", "LogarithmPlotter.qml"))) - if not engine.rootObjects(): print("No root object", path.realpath(path.join(getcwd(), "qml"))) @@ -135,26 +134,26 @@ def run(): # Open the current diagram chdir(pwd) if len(argv) > 0 and path.exists(argv[-1]) and argv[-1].split('.')[-1] in ['lpf']: - engine.rootObjects()[0].loadDiagram(argv[-1]) + js_globals.Modules.IO.loadDiagram(argv[-1]) chdir(path.dirname(path.realpath(__file__))) - + if platform == "darwin": - macOSFileOpenHandler.init_graphics(engine.rootObjects()[0]) - + macOSFileOpenHandler.init_io(js_globals.Modules.IO) + # Check for LaTeX installation if LaTeX support is enabled if config.getSetting("enable_latex"): latex.check_latex_install() - + # Check for updates if config.getSetting("check_for_updates"): check_for_updates(__VERSION__, engine.rootObjects()[0]) - + exit_code = app.exec() - + tempdir.cleanup() config.save() exit(exit_code) + if __name__ == "__main__": run() - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 3fb9697..388264c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -86,19 +86,19 @@ ApplicationWindow { width: parent.width anchors.top: parent.top TabButton { - text: qsTr("Objects") + text: qsTranslate('io', "Objects") icon.name: 'polygon-add-nodes' icon.color: sysPalette.windowText //height: 24 } TabButton { - text: qsTr("Settings") + text: qsTranslate('io', "Settings") icon.name: 'preferences-system-symbolic' icon.color: sysPalette.windowText //height: 24 } TabButton { - text: qsTr("History") + text: qsTranslate('io', "History") icon.name: 'view-history' icon.color: sysPalette.windowText //height: 24 @@ -159,7 +159,7 @@ ApplicationWindow { property bool firstDrawDone: false - onPainted: if(!firstDrawDone) { + onPainted: if(!firstDrawDone) { firstDrawDone = true; console.info("First paint done in " + (new Date().getTime()-(StartTime*1000)) + "ms") if(TestBuild == true) { @@ -182,130 +182,6 @@ ApplicationWindow { } } - /*! - \qmlmethod void LogarithmPlotter::saveDiagram(string filename) - Saves the diagram to a certain \c filename. - */ - function saveDiagram(filename) { - if(['lpf'].indexOf(filename.split('.')[filename.split('.').length-1]) == -1) - filename += '.lpf' - settings.saveFilename = filename - var objs = {} - for(var objType in Modules.Objects.currentObjects){ - objs[objType] = [] - for(var obj of Modules.Objects.currentObjects[objType]) { - objs[objType].push(obj.export()) - } - } - Helper.write(filename, JSON.stringify({ - "xzoom": settings.xzoom, - "yzoom": settings.yzoom, - "xmin": settings.xmin, - "ymax": settings.ymax, - "xaxisstep": settings.xaxisstep, - "yaxisstep": settings.yaxisstep, - "xaxislabel": settings.xlabel, - "yaxislabel": settings.ylabel, - "logscalex": settings.logscalex, - "linewidth": settings.linewidth, - "showxgrad": settings.showxgrad, - "showygrad": settings.showygrad, - "textsize": settings.textsize, - "history": history.serialize(), - "width": root.width, - "height": root.height, - "objects": objs, - "type": "logplotv1" - })) - alert.show(qsTr("Saved plot to '%1'.").arg(filename.split("/").pop())) - history.saved = true - } - - /*! - \qmlmethod void LogarithmPlotter::saveDiagram(string filename) - Loads the diagram from a certain \c filename. - */ - function loadDiagram(filename) { - let basename = filename.split("/").pop() - alert.show(qsTr("Loading file '%1'.").arg(basename)) - let data = JSON.parse(Helper.load(filename)) - let error = ""; - if(Object.keys(data).includes("type") && data["type"] == "logplotv1") { - history.clear() - // Importing settings - settings.saveFilename = filename - settings.xzoom = data["xzoom"] - settings.yzoom = data["yzoom"] - settings.xmin = data["xmin"] - settings.ymax = data["ymax"] - settings.xaxisstep = data["xaxisstep"] - settings.yaxisstep = data["yaxisstep"] - settings.xlabel = data["xaxislabel"] - settings.ylabel = data["yaxislabel"] - settings.logscalex = data["logscalex"] - if("showxgrad" in data) - settings.showxgrad = data["showxgrad"] - if("showygrad" in data) - settings.textsize = data["showygrad"] - if("linewidth" in data) - settings.linewidth = data["linewidth"] - if("textsize" in data) - settings.textsize = data["textsize"] - root.height = data["height"] - root.width = data["width"] - - // Importing objects - Modules.Objects.currentObjects = {} - Modules.Object.keys(Objects.currentObjectsByName).forEach(key => { - delete Modules.Objects.currentObjectsByName[key]; - // Required to keep the same reference for the copy of the object used in expression variable detection. - // Another way would be to change the reference as well, but I feel like the code would be less clean. - }) - for(let objType in data['objects']) { - if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { - Modules.Objects.currentObjects[objType] = [] - for(let objData of data['objects'][objType]) { - let obj = new Modules.Objects.types[objType](...objData) - Modules.Objects.currentObjects[objType].push(obj) - Modules.Objects.currentObjectsByName[obj.name] = obj - } - } else { - error += qsTr("Unknown object type: %1.").arg(objType) + "\n"; - } - } - - // Updating object dependencies. - for(let objName in Modules.Objects.currentObjectsByName) - Modules.Objects.currentObjectsByName[objName].update() - - // Importing history - if("history" in data) - history.unserialize(...data["history"]) - - // Refreshing sidebar - if(sidebarSelector.currentIndex == 0) { - // For some reason, if we load a file while the tab is on object, - // we get stuck in a Qt-side loop? Qt bug or side-effect here, I don't know. - sidebarSelector.currentIndex = 1 - objectLists.update() - delayRefreshTimer.start() - } else { - objectLists.update() - } - } else { - error = qsTr("Invalid file provided.") - } - if(error != "") { - console.log(error) - alert.show(qsTr("Could not save file: ") + error) - // TODO: Error handling - return - } - drawCanvas.requestPaint() - alert.show(qsTr("Loaded file '%1'.").arg(basename)) - history.saved = true - } - Timer { id: delayRefreshTimer repeat: false @@ -327,6 +203,22 @@ ApplicationWindow { } } + /*! + \qmlmethod void LogarithmPlotter::updateObjectsLists() + Updates the objects lists when loading a file. + */ + function updateObjectsLists() { + if(sidebarSelector.currentIndex === 0) { + // For some reason, if we load a file while the tab is on object, + // we get stuck in a Qt-side loop? Qt bug or side-effect here, I don't know. + sidebarSelector.currentIndex = 1 + objectLists.update() + delayRefreshTimer.start() + } else { + objectLists.update() + } + } + /*! \qmlmethod void LogarithmPlotter::copyDiagramToClipboard() Copies the current diagram image to the clipboard. @@ -335,7 +227,7 @@ ApplicationWindow { var file = Helper.gettmpfile() drawCanvas.save(file) Helper.copyImageToClipboard() - alert.show(qsTr("Copied plot screenshot to clipboard!")) + alert.show(qsTranslate('io', "Copied plot screenshot to clipboard!")) } /*! @@ -350,11 +242,11 @@ ApplicationWindow { Menu { id: updateMenu - title: qsTr("&Update") + title: qsTranslate('io', "&Update") Action { - text: qsTr("&Update LogarithmPlotter") + text: qsTranslate('io', "&Update LogarithmPlotter") icon.name: 'update' - onTriggered: Qt.openUrlExternally("https://dev.apps.ad5001.eu/logarithmplotter") + onTriggered: Qt.openUrlExternally("https://apps.ad5001.eu/logarithmplotter/") } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index b15caed..cf09695 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -127,6 +127,10 @@ ScrollView { */ property string saveFilename: "" + Component.onCompleted: { + Modules.IO.initialize(root, settings, alert) + } + Column { spacing: 10 width: parent.width @@ -138,9 +142,9 @@ ScrollView { var filePath = fdiag.currentFile.toString().substr(7) settings.saveFilename = filePath if(exportMode) { - root.saveDiagram(filePath) + Modules.IO.saveDiagram(filePath) } else { - root.loadDiagram(filePath) + Modules.IO.loadDiagram(filePath) if(xAxisLabel.find(settings.xlabel) == -1) xAxisLabel.model.append({text: settings.xlabel}) xAxisLabel.editText = settings.xlabel if(yAxisLabel.find(settings.ylabel) == -1) yAxisLabel.model.append({text: settings.ylabel}) @@ -442,7 +446,7 @@ ScrollView { if(settings.saveFilename == "") { saveAs() } else { - root.saveDiagram(settings.saveFilename) + Modules.IO.saveDiagram(settings.saveFilename) } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js index 4c79c64..9f207a0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js @@ -5,4 +5,5 @@ .import "objs/autoload.mjs" as Autoload .import "math/latex.mjs" as Latex .import "history/common.mjs" as HistoryCommon -.import "canvas.mjs" as CanvasAPI \ No newline at end of file +.import "canvas.mjs" as CanvasAPI +.import "io.mjs" as IOAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index b662098..66d35fd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -34,7 +34,10 @@ class HistoryCommonAPI extends Module { undo() { this.history.undo() } redo() { this.history.redo() } + clear() { this.history.clear() } addToHistory(action) { this.history.addToHistory(action) } + unserialize(data) { this.history.unserialize(data) } + serialize() { return this.history.serialize() } } /** @type {HistoryCommonAPI} */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs new file mode 100644 index 0000000..fe87ad8 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -0,0 +1,168 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {Module} from "./modules.mjs" + +class IOAPI extends Module { + + constructor() { + super('IO', [ + Modules.Objects, + Modules.History + ]) + /** + * Path of the currently opened file. Empty if no file is opened. + * @type {string} + */ + this.saveFileName = "" + } + + /** + * Initializes module with QML elements. + * @param {LogarithmPlotter} rootElement + * @param {Settings} settings + * @param {{show: function(string)}} alert + */ + initialize(rootElement, settings, alert) { + this.rootElement = rootElement + this.settings = settings + this.alert = alert + } + + /** + * Saves the diagram to a certain \c filename. + * @param {string} filename + */ + saveDiagram(filename) { + // Add extension if necessary + if(['lpf'].indexOf(filename.split('.')[filename.split('.').length-1]) === -1) + filename += '.lpf' + this.saveFilename = filename + let objs = {} + for(let objType in Modules.Objects.currentObjects){ + objs[objType] = [] + for(let obj of Modules.Objects.currentObjects[objType]) { + objs[objType].push(obj.export()) + } + } + let settings = { + "xzoom": this.settings.xzoom, + "yzoom": this.settings.yzoom, + "xmin": this.settings.xmin, + "ymax": this.settings.ymax, + "xaxisstep": this.settings.xaxisstep, + "yaxisstep": this.settings.yaxisstep, + "xaxislabel": this.settings.xlabel, + "yaxislabel": this.settings.ylabel, + "logscalex": this.settings.logscalex, + "linewidth": this.settings.linewidth, + "showxgrad": this.settings.showxgrad, + "showygrad": this.settings.showygrad, + "textsize": this.settings.textsize, + "history": Modules.History.serialize(), + "width": this.rootElement.width, + "height": this.rootElement.height, + "objects": objs, + "type": "logplotv1" + } + Helper.write(filename, JSON.stringify(settings)) + this.alert.show(qsTranslate('io', "Saved plot to '%1'.").arg(filename.split("/").pop())) + Modules.History.history.saved = true + } + + /** + * Loads the diagram from a certain \c filename. + * @param {string} filename + */ + loadDiagram(filename) { + let basename = filename.split("/").pop() + this.alert.show(qsTranslate('io', "Loading file '%1'.").arg(basename)) + let data = JSON.parse(Helper.load(filename)) + let error = ""; + if(Object.keys(data).includes("type") && data["type"] === "logplotv1") { + Modules.History.clear() + // Importing settings + this.settings.saveFilename = filename + this.settings.xzoom = data["xzoom"] + this.settings.yzoom = data["yzoom"] + this.settings.xmin = data["xmin"] + this.settings.ymax = data["ymax"] + this.settings.xaxisstep = data["xaxisstep"] + this.settings.yaxisstep = data["yaxisstep"] + this.settings.xlabel = data["xaxislabel"] + this.settings.ylabel = data["yaxislabel"] + this.settings.logscalex = data["logscalex"] + if("showxgrad" in data) + this.settings.showxgrad = data["showxgrad"] + if("showygrad" in data) + this.settings.textsize = data["showygrad"] + if("linewidth" in data) + this.settings.linewidth = data["linewidth"] + if("textsize" in data) + this.settings.textsize = data["textsize"] + this.rootElement.height = data["height"] + this.rootElement.width = data["width"] + + // Importing objects + Modules.Objects.currentObjects = {} + for(let key of Object.keys(Modules.Objects.currentObjectsByName)) { + delete Modules.Objects.currentObjectsByName[key]; + // Required to keep the same reference for the copy of the object used in expression variable detection. + // Another way would be to change the reference as well, but I feel like the code would be less clean. + } + for(let objType in data['objects']) { + if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { + Modules.Objects.currentObjects[objType] = [] + for(let objData of data['objects'][objType]) { + let obj = new Modules.Objects.types[objType](...objData) + Modules.Objects.currentObjects[objType].push(obj) + Modules.Objects.currentObjectsByName[obj.name] = obj + } + } else { + error += qsTranslate('io', "Unknown object type: %1.").arg(objType) + "\n"; + } + } + + // Updating object dependencies. + for(let objName in Modules.Objects.currentObjectsByName) + Modules.Objects.currentObjectsByName[objName].update() + + // Importing history + if("history" in data) + Modules.History.unserialize(...data["history"]) + + // Refreshing sidebar + this.rootElement.updateObjectsLists() + } else { + error = qsTranslate('io', "Invalid file provided.") + } + if(error !== "") { + console.log(error) + this.alert.show(qsTranslate('io', "Could not save file: ") + error) + // TODO: Error handling + return + } + Modules.Canvas.redraw() + this.alert.show(qsTranslate('io', "Loaded file '%1'.").arg(basename)) + Modules.History.history.saved = true + } + +} + +/** @type {IOAPI} */ +Modules.IO = Modules.IO || new IOAPI() diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index f19e000..bdd11b7 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -47,7 +47,7 @@ CONFIG_PATH = { CONFIG_FILE = path.join(CONFIG_PATH, "config.json") initialized = False -current_config= DEFAULT_SETTINGS +current_config = DEFAULT_SETTINGS def init(): diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index 127e587..e6e9dfb 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -31,11 +31,12 @@ from urllib.error import HTTPError, URLError from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config + class ChangelogFetcher(QRunnable): def __init__(self, helper): QRunnable.__init__(self) self.helper = helper - + def run(self): msg_text = "Unknown changelog error." try: @@ -43,17 +44,19 @@ class ChangelogFetcher(QRunnable): r = urlopen("https://api.ad5001.eu/changelog/logarithmplotter/?version=" + __VERSION__) lines = r.readlines() r.close() - msg_text = "".join(map(lambda x: x.decode('utf-8'), lines)).strip() + msg_text = "".join(map(lambda x: x.decode('utf-8'), lines)).strip() except HTTPError as e: - msg_text = QCoreApplication.translate("changelog","Could not fetch changelog: Server error {}.").format(str(e.code)) + msg_text = QCoreApplication.translate("changelog", "Could not fetch changelog: Server error {}.").format( + str(e.code)) except URLError as e: - msg_text = QCoreApplication.translate("changelog","Could not fetch update: {}.").format(str(e.reason)) + msg_text = QCoreApplication.translate("changelog", "Could not fetch update: {}.").format(str(e.reason)) self.helper.gotChangelog.emit(msg_text) + class Helper(QObject): changelogFetched = Signal(str) gotChangelog = Signal(str) - + def __init__(self, cwd: str, tmpfile: str): QObject.__init__(self) self.cwd = cwd @@ -62,7 +65,7 @@ class Helper(QObject): def fetched(self, changelog: str): self.changelogFetched.emit(changelog) - + @Slot(str, str) def write(self, filename, filedata): chdir(self.cwd) @@ -70,17 +73,17 @@ class Helper(QObject): if filename.split(".")[-1] == "lpf": # Add header to file filedata = "LPFv1" + filedata - f = open(path.realpath(filename), 'w', -1, 'utf8') + f = open(path.realpath(filename), 'w', -1, 'utf8') f.write(filedata) f.close() chdir(path.dirname(path.realpath(__file__))) - + @Slot(str, result=str) def load(self, filename): chdir(self.cwd) data = '{}' if path.exists(path.realpath(filename)): - f = open(path.realpath(filename), 'r', -1, 'utf8') + f = open(path.realpath(filename), 'r', -1, 'utf8') data = f.read() f.close() try: @@ -94,10 +97,13 @@ class Helper(QObject): raise Exception(QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.".format(__VERSION__))) else: raise Exception("Invalid LogarithmPlotter file.") - except Exception as e: # If file can't be loaded - QMessageBox.warning(None, 'LogarithmPlotter', QCoreApplication.translate('main','Could not open file "{}":\n{}').format(filename, e), QMessageBox.Ok) # Cannot parse file + except Exception as e: # If file can't be loaded + QMessageBox.warning(None, 'LogarithmPlotter', + QCoreApplication.translate('main', 'Could not open file "{}":\n{}').format(filename, + e), + QMessageBox.Ok) # Cannot parse file else: - QMessageBox.warning(None, 'LogarithmPlotter', QCoreApplication.translate('main','Could not open file: "{}"\nFile does not exist.').format(filename), QMessageBox.Ok) # Cannot parse file + QMessageBox.warning(None, 'LogarithmPlotter', QCoreApplication.translate('main', 'Could not open file: "{}"\nFile does not exist.').format(filename), QMessageBox.Ok) # Cannot parse file try: chdir(path.dirname(path.realpath(__file__))) except NotADirectoryError as e: @@ -105,60 +111,62 @@ class Helper(QObject): # See more at https://git.ad5001.eu/Ad5001/LogarithmPlotter/issues/1 pass return data - + @Slot(result=str) def gettmpfile(self): return self.tmpfile - + @Slot() def copyImageToClipboard(self): clipboard = QApplication.clipboard() clipboard.setImage(QImage(self.tmpfile)) - + @Slot(result=str) def getVersion(self): return __VERSION__ - + @Slot(str, result=str) def getSetting(self, namespace): return config.getSetting(namespace) - + @Slot(str, result=int) def getSettingInt(self, namespace): return config.getSetting(namespace) - + @Slot(str, result=bool) def getSettingBool(self, namespace): return config.getSetting(namespace) - + @Slot(str, str) def setSetting(self, namespace, value): return config.setSetting(namespace, value) - + @Slot(str, bool) def setSettingBool(self, namespace, value): return config.setSetting(namespace, value) - + @Slot(str, int) def setSettingInt(self, namespace, value): return config.setSetting(namespace, value) - + @Slot(str) def setLanguage(self, new_lang): config.setSetting("language", new_lang) - + @Slot(result=str) def getDebugInfos(self): """ Returns the version info about Qt, PySide6 & Python """ - return QCoreApplication.translate('main',"Built with PySide6 (Qt) v{} and python v{}").format(PySide6_version, sys_version.split("\n")[0]) - + return QCoreApplication.translate('main', "Built with PySide6 (Qt) v{} and python v{}").format(PySide6_version, + sys_version.split( + "\n")[0]) + @Slot() def fetchChangelog(self): changelog_cache_path = path.join(path.dirname(path.realpath(__file__)), "CHANGELOG.md") print(changelog_cache_path) - if path.exists(changelog_cache_path): + if path.exists(changelog_cache_path): # We have a cached version of the changelog, for env that don't have access to the internet. f = open(changelog_cache_path); self.changelogFetched.emit("".join(f.readlines()).strip()) @@ -167,4 +175,3 @@ class Helper(QObject): # Fetch it from the internet. runnable = ChangelogFetcher(self) QThreadPool.globalInstance().start(runnable) - diff --git a/LogarithmPlotter/util/js.py b/LogarithmPlotter/util/js.py new file mode 100644 index 0000000..4514a42 --- /dev/null +++ b/LogarithmPlotter/util/js.py @@ -0,0 +1,52 @@ +""" + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +""" + +from PySide6.QtQml import QJSValue + + +class PyJSValue: + """ + Wrapper to provide easy way to interact with JavaScript values in Python directly. + """ + def __init__(self, js_value: QJSValue, parent: QJSValue = None): + self.qjs_value = js_value + self._parent = parent + + def __getattr__(self, item): + return PyJSValue(self.qjs_value.property(item), self.qjs_value) + + def __setattr__(self, key, value): + if key in ['qjs_value', '_parent']: + # Fallback + object.__setattr__(self, key, value) + elif isinstance(value, PyJSValue): + # Set property + self.qjs_value.setProperty(key, value.qjs_value) + else: + print('Setting', key, value) + self.qjs_value.setProperty(key, value) + + def __call__(self, *args, **kwargs): + if self.qjs_value.isCallable(): + if self._parent is None: + return self.qjs_value.call(args) + else: + return self.qjs_value.callWithInstance(self._parent, args) + else: + raise ValueError('Cannot call non-function JS value.') + diff --git a/LogarithmPlotter/util/latex.py b/LogarithmPlotter/util/latex.py index d519e18..c670e1e 100644 --- a/LogarithmPlotter/util/latex.py +++ b/LogarithmPlotter/util/latex.py @@ -160,10 +160,7 @@ class Latex(QObject): QCoreApplication.translate("latex", "An exception occured within the creation of the latex formula.\nProcess '{}' ended with a non-zero return code {}:\n\n{}\nPlease make sure your latex installation is correct and report a bug if so.") .format(" ".join(process), proc.returncode, str(out, 'utf8') + "\n" + str(err, 'utf8'))) - raise Exception( - " ".join(process) + " process exited with return code " + str(proc.returncode) + ":\n" + str(out, - 'utf8') + "\n" + str( - err, 'utf8')) + raise Exception("{0} process exited with return code {1}:\n{2}\n{3}".format(" ".join(process), str(proc.returncode), str(out, 'utf8'), str(err, 'utf8'))) except TimeoutExpired as e: # Process timed out proc.kill() diff --git a/LogarithmPlotter/util/native.py b/LogarithmPlotter/util/native.py index 01d9022..7e32119 100644 --- a/LogarithmPlotter/util/native.py +++ b/LogarithmPlotter/util/native.py @@ -20,29 +20,30 @@ from PySide6.QtCore import QObject, QEvent + # On macOS, opening a file through finder can only be fetched through the -# QFileOpenEvent and NOT throught command line parameters. +# QFileOpenEvent and NOT through command line parameters. class MacOSFileOpenHandler(QObject): def __init__(self): - self.initilized = False - self.mainwindow = None + self.initialized = False + self.io_module = None self.opened_file = "" QObject.__init__(self) - - def init_graphics(self, mainwindow): - self.mainwindow = mainwindow - self.initilized = True + + def init_io(self, io_modules): + self.io_module = io_modules + self.initialized = True if self.opened_file != "": self.open_file() - + def open_file(self): - self.mainwindow.loadDiagram(self.opened_file) - + self.io_module.loadDiagram(self.opened_file) + def eventFilter(self, obj, event): if event.type() == QEvent.FileOpen: - print("Got file", event.file(), self.initilized) + print("Got file", event.file(), self.initialized) self.opened_file = event.file() - if self.initilized: + if self.initialized: self.open_file() return True else: diff --git a/LogarithmPlotter/util/update.py b/LogarithmPlotter/util/update.py index 25400ce..dbacbfe 100644 --- a/LogarithmPlotter/util/update.py +++ b/LogarithmPlotter/util/update.py @@ -21,9 +21,11 @@ from urllib.request import urlopen from urllib.error import HTTPError, URLError from sys import argv + class UpdateInformation(QObject): got_update_info = Signal(bool, str, bool) + class UpdateCheckerRunnable(QRunnable): def __init__(self, current_version, callback): QRunnable.__init__(self) @@ -40,44 +42,51 @@ class UpdateCheckerRunnable(QRunnable): lines = r.readlines() r.close() # Parsing version - version = "".join(map(chr, lines[0])).strip() # Converts byte to string. + version = "".join(map(chr, lines[0])).strip() # Converts byte to string. version_tuple = version.split(".") is_version_newer = False if "dev" in self.current_version: # We're on a dev version - current_version_tuple = self.current_version.split(".")[:-1] # Removing the dev0+git bit. - is_version_newer = version_tuple >= current_version_tuple # If equals, that means we got out of testing phase. + current_version_tuple = self.current_version.split(".")[:-1] # Removing the dev0+git bit. + is_version_newer = version_tuple >= current_version_tuple # If equals, that means we got out of testing phase. else: current_version_tuple = self.current_version.split(".") is_version_newer = version_tuple > current_version_tuple if is_version_newer: - msg_text = QCoreApplication.translate("update","An update for LogarithPlotter (v{}) is available.").format(version) + msg_text = QCoreApplication.translate("update", + "An update for LogarithPlotter (v{}) is available.").format( + version) update_available = True else: show_alert = False - msg_text = QCoreApplication.translate("update","No update available.") - + msg_text = QCoreApplication.translate("update", "No update available.") + except HTTPError as e: - msg_text = QCoreApplication.translate("update","Could not fetch update information: Server error {}.").format(str(e.code)) + msg_text = QCoreApplication.translate("update", + "Could not fetch update information: Server error {}.").format( + str(e.code)) except URLError as e: - msg_text = QCoreApplication.translate("update","Could not fetch update information: {}.").format(str(e.reason)) - self.callback.got_update_info.emit(show_alert, msg_text,update_available) + msg_text = QCoreApplication.translate("update", "Could not fetch update information: {}.").format( + str(e.reason)) + self.callback.got_update_info.emit(show_alert, msg_text, update_available) + def check_for_updates(current_version, window): """ Checks for updates in the background, and sends an alert with information. """ if "--no-check-for-updates" in argv: - return # + return + def cb(show_alert, msg_text, update_available): pass if show_alert: window.showAlert(msg_text) if update_available: window.showUpdateMenu() - + update_info = UpdateInformation() update_info.got_update_info.connect(cb) - + runnable = UpdateCheckerRunnable(current_version, update_info) QThreadPool.globalInstance().start(runnable) From 8e75f13e9a9417c60bf5729d705247a27f0621b3 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Fri, 29 Mar 2024 17:56:09 +0100 Subject: [PATCH 186/436] Removing vanished translations. --- LogarithmPlotter/i18n/lp_de.ts | 236 +++++++++++++++--------------- LogarithmPlotter/i18n/lp_en.ts | 236 +++++++++++++++--------------- LogarithmPlotter/i18n/lp_fr.ts | 236 +++++++++++++++--------------- LogarithmPlotter/i18n/lp_hu.ts | 232 ++++++++++++++--------------- LogarithmPlotter/i18n/lp_nb_NO.ts | 92 ++++++------ 5 files changed, 516 insertions(+), 516 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 407b284..4d9a064 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Eigenschaften von %1 %2 bearbeiten + Eigenschaften von %1 %2 bearbeiten Name - Name + Name Label content - Etikett + Etikett null - leer + leer name - Name + Name name + value - Name + Wert + Name + Wert + Create new %1 - + Neues %1objekt erstellen + + Neues %1objekt erstellen @@ -438,51 +438,51 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter Objects - Objekte + Objekte Settings - Einstellungen + Einstellungen History - Verlauf + Verlauf Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. Copied plot screenshot to clipboard! - Grafik in die Zwischenablage kopiert! + Grafik in die Zwischenablage kopiert! &Update - &Aktualisieren + &Aktualisieren &Update LogarithmPlotter - LogarithmPlotter &aktualisieren + LogarithmPlotter &aktualisieren @@ -507,23 +507,23 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Hide %1 %2 - Ausblenden %1 %2 + Ausblenden %1 %2 Show %1 %2 - Anzeigen %1 %2 + Anzeigen %1 %2 Set %1 %2 position - Position von %1 %2 einstellen + Position von %1 %2 einstellen Delete %1 %2 - %1 %2 löschen + %1 %2 löschen Pick new color for %1 %2 - Neue Farbe für %1 %2 auswählen + Neue Farbe für %1 %2 auswählen @@ -563,7 +563,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Snap to grid - Am Gitter einrasten + Am Gitter einrasten @@ -804,30 +804,30 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" color %1 %2's color changed from %3 to %4. - %1 %2 wurde von %3 bis %4 umgefärbt. + %1 %2 wurde von %3 bis %4 umgefärbt. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + Beispiel: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) + Die folgenden Parameter werden verwendet, wenn der Definitionsbereich eine nicht kontinuierliche Menge ist. (Beispiel: ℕ, ℤ, Mengen wie {0;3}...) Note: Specify the probability for each value. - Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. + Hinweis: Geben Sie die Wahrscheinlichkeit für jeden Wert an. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… + Hinweis: Verwenden Sie %1[n], um sich auf %1ₙ zu beziehen, %1[n+1] für %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. + Wenn Sie Latex aktiviert haben, können Sie Latex-Auszeichnungen zwischen $$ verwenden, um Gleichungen zu erstellen. @@ -846,25 +846,25 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" create New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. delete %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 of %2 changed from %3 to %4. - %1 von %2 wurde von %3 auf %4 geändert. + %1 von %2 wurde von %3 auf %4 geändert. @@ -931,11 +931,11 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Function definition is not permitted. - Funktionsdefinition ist nicht erlaubt. + Funktionsdefinition ist nicht erlaubt. Expected variable for assignment. - Erwartete Variable für Zuweisung. + Erwartete Variable für Zuweisung. @@ -1080,57 +1080,57 @@ Ausdruck analysiert: %3 function Function - Funktion + Funktion Functions - Funktionen + Funktionen gainbode Bode Magnitude - Bode-Magnitude + Bode-Magnitude Bode Magnitudes - Bode-Magnituden + Bode-Magnituden low-pass - Tiefpass + Tiefpass high-pass - Hochpass + Hochpass historylib New %1 %2 created. - Neu %1 %2 erstellt. + Neu %1 %2 erstellt. %1 %2 deleted. - %1 %2 gelöscht. + %1 %2 gelöscht. %1 of %2 %3 changed from "%4" to "%5". - %1 von %2 %3 wurde von "%4" auf "%5" geändert. + %1 von %2 %3 wurde von "%4" auf "%5" geändert. %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. Name of %1 %2 changed to %3. - Der Name von %1 %2 wurde in %3 geändert. + Der Name von %1 %2 wurde in %3 geändert. @@ -1241,293 +1241,293 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde name %1 %2 renamed to %3. - %1 %2 umbenannt in %3. + %1 %2 umbenannt in %3. parameters above - ↑ Über + ↑ Über below - ↓ Unter + ↓ Unter left - ← Links + ← Links right - → Rechts + → Rechts above-left - ↖ Oben links + ↖ Oben links above-right - ↗ Oben rechts + ↗ Oben rechts below-left - ↙ Unten links + ↙ Unten links below-right - ↘ Unten rechts + ↘ Unten rechts center - >|< Zentrum + >|< Zentrum top - ↑ Über + ↑ Über bottom - ↓ Unter + ↓ Unter top-left - ↖ Oben links + ↖ Oben links top-right - ↗ Oben rechts + ↗ Oben rechts bottom-left - ↙ Unten links + ↙ Unten links bottom-right - ↘ Unten rechts + ↘ Unten rechts application - Anwendung + Anwendung function - Funktion + Funktion high - Hoch + Hoch low - Tief + Tief Next to target - Neben dem Ziel + Neben dem Ziel With label - Mit Etikett + Mit Etikett Hidden - Versteckt + Versteckt phasebode Bode Phase - Bode-Phase + Bode-Phase Bode Phases - Bode-Phasen + Bode-Phasen point Point - Punkt + Punkt Points - Punkte + Punkte position Position of %1 %2 set from "%3" to "%4". - %1 %2 wurde von "%3" nach "%4" verschoben. + %1 %2 wurde von "%3" nach "%4" verschoben. Position of %1 set from %2 to %3. - %1 wurde von %2 nach %3 verschoben. + %1 wurde von %2 nach %3 verschoben. prop expression - Ausdruck + Ausdruck definitionDomain - Definitionsbereich + Definitionsbereich destinationDomain - Reichweite + Reichweite labelPosition - Position des Etiketts + Position des Etiketts displayMode - Anzeigemodus + Anzeigemodus labelX - X-Position des Etiketts + X-Position des Etiketts drawPoints - Unentschiedene Punkte + Unentschiedene Punkte drawDashedLines - Gestrichelte Linien anzeigen + Gestrichelte Linien anzeigen om_0 - ω₀ + ω₀ pass - Pass + Pass gain - Größenordnung + Größenordnung omGraduation - Teilung auf ω zeigen + Teilung auf ω zeigen phase - Phase + Phase unit - Einheit + Einheit x - X + X y - Y + Y pointStyle - Punkt-Stil + Punkt-Stil probabilities - Wahrscheinlichkeiten + Wahrscheinlichkeiten text - Inhalt + Inhalt disableLatex - LaTeX-Rendering für diesen Text deaktivieren + LaTeX-Rendering für diesen Text deaktivieren targetElement - Zielobjekt + Zielobjekt approximate - Ungefähren Wert anzeigen + Ungefähren Wert anzeigen rounding - Rundung + Rundung displayStyle - Stil + Stil targetValuePosition - Wertposition des Ziels + Wertposition des Ziels defaultExpression - Standardausdruck + Standardausdruck baseValues - Initialisierungswerte + Initialisierungswerte color - Farbe + Farbe repartition Repartition - Verteilungsfunktion + Verteilungsfunktion Repartition functions - Verteilungsfunktionen + Verteilungsfunktionen sequence Sequence - Folge + Folge Sequences - Folgen + Folgen sommegainsbode Bode Magnitudes Sum - Bode-Magnituden Summe + Bode-Magnituden Summe sommephasesbode Bode Phases Sum - Bode-Phasen Summe + Bode-Phasen Summe text Text - Text + Text Texts - Texte + Texte @@ -1595,22 +1595,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde visibility %1 %2 shown. - %1 %2 angezeigt. + %1 %2 angezeigt. %1 %2 hidden. - %1 %2 ausgeblendet. + %1 %2 ausgeblendet. xcursor X Cursor - X Zeiger + X Zeiger X Cursors - X Zeiger + X Zeiger diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index f700aa6..f565fe7 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Edit properties of %1 %2 + Edit properties of %1 %2 Name - Name + Name Label content - Label content + Label content null - null + null name - name + name name + value - name + value + name + value + Create new %1 - + Create new %1 + + Create new %1 @@ -438,51 +438,51 @@ These settings can be changed at any time from the "Settings" menu.LogarithmPlotter Objects - Objects + Objects Settings - Settings + Settings History - History + History Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. Loading file '%1'. - Loading file '%1'. + Loading file '%1'. Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. Invalid file provided. - Invalid file provided. + Invalid file provided. Could not save file: - Could not save file: + Could not save file: Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. Copied plot screenshot to clipboard! - Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! &Update - &Update + &Update &Update LogarithmPlotter - &Update LogarithmPlotter + &Update LogarithmPlotter @@ -507,23 +507,23 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - Hide %1 %2 + Hide %1 %2 Show %1 %2 - Show %1 %2 + Show %1 %2 Set %1 %2 position - Set %1 %2 position + Set %1 %2 position Delete %1 %2 - Delete %1 %2 + Delete %1 %2 Pick new color for %1 %2 - Pick new color for %1 %2 + Pick new color for %1 %2 @@ -563,7 +563,7 @@ These settings can be changed at any time from the "Settings" menu. Snap to grid - Snap to grid + Snap to grid @@ -804,30 +804,30 @@ These settings can be changed at any time from the "Settings" menu.color %1 %2's color changed from %3 to %4. - %1 %2's color changed from %3 to %4. + %1 %2's color changed from %3 to %4. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) + The following parameters are used when the domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}…) Note: Specify the probability for each value. - Note: Specify the probability for each value. + Note: Specify the probability for each value. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - If you have latex enabled, you can use use latex markup in between $$ to create equations. + If you have latex enabled, you can use use latex markup in between $$ to create equations. @@ -846,25 +846,25 @@ These settings can be changed at any time from the "Settings" menu.create New %1 %2 created. - New %1 %2 created. + New %1 %2 created. delete %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 of %2 changed from %3 to %4. - %1 of %2 changed from %3 to %4. + %1 of %2 changed from %3 to %4. @@ -931,11 +931,11 @@ These settings can be changed at any time from the "Settings" menu. Function definition is not permitted. - Function definition is not permitted. + Function definition is not permitted. Expected variable for assignment. - Expected variable for assignment. + Expected variable for assignment. @@ -1080,57 +1080,57 @@ Evaluated expression: %3 function Function - Function + Function Functions - Functions + Functions gainbode Bode Magnitude - Bode Magnitude + Bode Magnitude Bode Magnitudes - Bode Magnitudes + Bode Magnitudes low-pass - low-pass + low-pass high-pass - high-pass + high-pass historylib New %1 %2 created. - New %1 %2 created. + New %1 %2 created. %1 %2 deleted. - %1 %2 deleted. + %1 %2 deleted. %1 of %2 %3 changed from "%4" to "%5". - %1 of %2 %3 changed from "%4" to "%5". + %1 of %2 %3 changed from "%4" to "%5". %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. Name of %1 %2 changed to %3. - Name of %1 %2 changed to %3. + Name of %1 %2 changed to %3. @@ -1241,293 +1241,293 @@ Please make sure your LaTeX installation is correct and report a bug if so.name %1 %2 renamed to %3. - %1 %2 renamed to %3. + %1 %2 renamed to %3. parameters above - ↑ Above + ↑ Above below - ↓ Below + ↓ Below left - ← Left + ← Left right - → Right + → Right above-left - ↖ Above left + ↖ Above left above-right - ↗ Above right + ↗ Above right below-left - ↙ Below left + ↙ Below left below-right - ↘ Below right + ↘ Below right center - >|< Center + >|< Center top - ↑ Top + ↑ Top bottom - ↓ Bottom + ↓ Bottom top-left - ↖ Top left + ↖ Top left top-right - ↗ Top right + ↗ Top right bottom-left - ↙ Bottom left + ↙ Bottom left bottom-right - ↘ Bottom right + ↘ Bottom right application - Application + Application function - Function + Function high - High + High low - Low + Low Next to target - Next to target + Next to target With label - With label + With label Hidden - Hidden + Hidden phasebode Bode Phase - Bode Phase + Bode Phase Bode Phases - Bode Phases + Bode Phases point Point - Point + Point Points - Points + Points position Position of %1 %2 set from "%3" to "%4". - %1 %2 moved from "%3" to "%4". + %1 %2 moved from "%3" to "%4". Position of %1 set from %2 to %3. - %1 moved from %2 to %3. + %1 moved from %2 to %3. prop expression - Expression + Expression definitionDomain - Domain + Domain destinationDomain - Range + Range labelPosition - Label position + Label position displayMode - Display mode + Display mode labelX - Label's X position + Label's X position drawPoints - Show points + Show points drawDashedLines - Show dashed lines + Show dashed lines om_0 - ω₀ + ω₀ pass - Pass + Pass gain - Magnitude gain + Magnitude gain omGraduation - Show graduation on ω₀ + Show graduation on ω₀ phase - Phase + Phase unit - Unit to use + Unit to use x - X + X y - Y + Y pointStyle - Point style + Point style probabilities - Probabilities list + Probabilities list text - Content + Content disableLatex - Disable LaTeX rendering for this text + Disable LaTeX rendering for this text targetElement - Object to target + Object to target approximate - Show approximate value + Show approximate value rounding - Rounding + Rounding displayStyle - Display style + Display style targetValuePosition - Target's value position + Target's value position defaultExpression - Default expression + Default expression baseValues - Initialisation values + Initialisation values color - Color + Color repartition Repartition - Distribution + Distribution Repartition functions - Distribution functions + Distribution functions sequence Sequence - Sequence + Sequence Sequences - Sequences + Sequences sommegainsbode Bode Magnitudes Sum - Bode Magnitudes Sum + Bode Magnitudes Sum sommephasesbode Bode Phases Sum - Bode Phases Sum + Bode Phases Sum text Text - Text + Text Texts - Texts + Texts @@ -1595,22 +1595,22 @@ Please make sure your LaTeX installation is correct and report a bug if so.visibility %1 %2 shown. - %1 %2 shown. + %1 %2 shown. %1 %2 hidden. - %1 %2 hidden. + %1 %2 hidden. xcursor X Cursor - X Cursor + X Cursor X Cursors - X Cursors + X Cursors diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index d1c0f95..f9671dc 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -261,32 +261,32 @@ EditorDialog Edit properties of %1 %2 - Changer les propriétés de %1 %2 + Changer les propriétés de %1 %2 Name - Nom + Nom Label content - Étiquette + Étiquette null - vide + vide name - nom + nom name + value - nom + valeur + nom + valeur + Create new %1 Traduction non litéralle pour éviter les problèmes de genre. - + Créer un nouvel objet %1 + + Créer un nouvel objet %1 @@ -446,51 +446,51 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter Objects - Objets + Objets Settings - Paramètres + Paramètres History - Historique + Historique Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. Copied plot screenshot to clipboard! - Image du graphe copiée dans le presse-papiers ! + Image du graphe copiée dans le presse-papiers ! &Update - &Mise à jour + &Mise à jour &Update LogarithmPlotter - &Mettre à jour LogarithmPlotter + &Mettre à jour LogarithmPlotter @@ -515,23 +515,23 @@ These settings can always be changed at any time from the "Settings" m Hide %1 %2 - Cacher l'objet %1 %2 + Cacher l'objet %1 %2 Show %1 %2 - Montrer l'objet %1 %2 + Montrer l'objet %1 %2 Set %1 %2 position - Définir la position de l'objet %1 %2 + Définir la position de l'objet %1 %2 Delete %1 %2 - Supprimer l'objet %1 %2 + Supprimer l'objet %1 %2 Pick new color for %1 %2 - Choisissez une nouvelle couleur pour %1 %2 + Choisissez une nouvelle couleur pour %1 %2 @@ -571,7 +571,7 @@ These settings can always be changed at any time from the "Settings" m Snap to grid - Placement sur la grille + Placement sur la grille @@ -812,31 +812,31 @@ These settings can always be changed at any time from the "Settings" m color %1 %2's color changed from %3 to %4. - %1 %2 a été re colorisé du %3 au %4. + %1 %2 a été re colorisé du %3 au %4. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Par exemple : R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) + Les paramètres suivants sont utilisés lorsque le domaine de définition est un ensemble non-continu. (Ex : ℕ, ℤ, des ensembles comme {0;3}…) Note: Specify the probability for each value. - Note : Spécifiez la probabilité pour chaque valeur. + Note : Spécifiez la probabilité pour chaque valeur. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁... - Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… + Note : Utilisez %1[n] pour faire référence à %1ₙ, %1[n+1] pour %1ₙ₊₁… If you have latex enabled, you can use use latex markup in between $$ to create equations. - Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. + Si vous avez activé le rendu latex, vous pouvez utiliser les balises latex entre $$ pour créer des équations. @@ -855,25 +855,25 @@ These settings can always be changed at any time from the "Settings" m create New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. delete %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). editproperty %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 of %2 changed from %3 to %4. - %1 de %2 modifiée de %3 à %4. + %1 de %2 modifiée de %3 à %4. @@ -940,11 +940,11 @@ These settings can always be changed at any time from the "Settings" m Function definition is not permitted. - La définition de fonctions n'est pas autorisée. + La définition de fonctions n'est pas autorisée. Expected variable for assignment. - Une variable est attendue pour l'affectation. + Une variable est attendue pour l'affectation. @@ -1089,57 +1089,57 @@ Formule analysée : %3 function Function - Fonction + Fonction Functions - Fonctions + Fonctions gainbode Bode Magnitude - Gain de Bode + Gain de Bode Bode Magnitudes - Gains de Bode + Gains de Bode low-pass - passe-bas + passe-bas high-pass - passe-haut + passe-haut historylib New %1 %2 created. - Nouvel objet %1 %2 créé. + Nouvel objet %1 %2 créé. %1 %2 deleted. - %1 %2 supprimé(e). + %1 %2 supprimé(e). %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 modifiée de "%4" à "%5". + %1 de %2 %3 modifiée de "%4" à "%5". %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). Name of %1 %2 changed to %3. - Le nom de %1 %2 a été changé en %3. + Le nom de %1 %2 a été changé en %3. @@ -1250,293 +1250,293 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c name %1 %2 renamed to %3. - %1 %2 renommé(e) en %3. + %1 %2 renommé(e) en %3. parameters above - ↑ Au dessus + ↑ Au dessus below - ↓ En dessous + ↓ En dessous left - ← À gauche + ← À gauche right - → À droite + → À droite above-left - ↖ Au dessus à gauche + ↖ Au dessus à gauche above-right - ↗ Au dessus à droite + ↗ Au dessus à droite below-left - ↙ En dessous à gauche + ↙ En dessous à gauche below-right - ↘ En dessous à droite + ↘ En dessous à droite center - >|< Centré + >|< Centré top - ↑ Au dessus + ↑ Au dessus bottom - ↓ En dessous + ↓ En dessous top-left - ↖ Au dessus à gauche + ↖ Au dessus à gauche top-right - ↗ Au dessus à droite + ↗ Au dessus à droite bottom-left - ↙ En dessous à gauche + ↙ En dessous à gauche bottom-right - ↘ En dessous à droite + ↘ En dessous à droite application - Application + Application function - Fonction + Fonction high - Haut + Haut low - Bas + Bas Next to target - A côté de la cible + A côté de la cible With label - Avec l'étiquette + Avec l'étiquette Hidden - Caché + Caché phasebode Bode Phase - Phase de Bode + Phase de Bode Bode Phases - Phases de Bode + Phases de Bode point Point - Point + Point Points - Points + Points position Position of %1 %2 set from "%3" to "%4". - %1 %2 a été déplacé depuis "%3" vers "%4". + %1 %2 a été déplacé depuis "%3" vers "%4". Position of %1 set from %2 to %3. - %1 a été déplacé depuis %2 vers %3. + %1 a été déplacé depuis %2 vers %3. prop expression - Expression + Expression definitionDomain - Domaine de définition + Domaine de définition destinationDomain - Portée + Portée labelPosition - Position de l'étiquette + Position de l'étiquette displayMode - Mode d'affichage + Mode d'affichage labelX - Position en X de l'étiquette + Position en X de l'étiquette drawPoints - Afficher les points + Afficher les points drawDashedLines - Afficher les pointillés + Afficher les pointillés om_0 - ω₀ + ω₀ pass - Passe + Passe gain - Gain + Gain omGraduation - Afficher la graduation sur ω₀ + Afficher la graduation sur ω₀ phase - Phase + Phase unit - Unité de la phase + Unité de la phase x - X + X y - Y + Y pointStyle - Style du point + Style du point probabilities - Liste de probabilités + Liste de probabilités text - Contenu + Contenu disableLatex - Désactiver le rendu LaTeX pour ce texte + Désactiver le rendu LaTeX pour ce texte targetElement - Objet à cibler + Objet à cibler approximate - Afficher la valeur approximative + Afficher la valeur approximative rounding - Arrondi + Arrondi displayStyle - Style d'affichage + Style d'affichage targetValuePosition - Position de la valeur de la cible + Position de la valeur de la cible defaultExpression - Expression + Expression baseValues - Valeurs d'initialisation + Valeurs d'initialisation color - Couleur + Couleur repartition Repartition - Répartition + Répartition Repartition functions - Fonctions de répartition + Fonctions de répartition sequence Sequence - Suite + Suite Sequences - Suites + Suites sommegainsbode Bode Magnitudes Sum - Sommes des gains de Bode + Sommes des gains de Bode sommephasesbode Bode Phases Sum - Somme des phases de Bode + Somme des phases de Bode text Text - Texte + Texte Texts - Textes + Textes @@ -1604,22 +1604,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c visibility %1 %2 shown. - %1 %2 affiché(e). + %1 %2 affiché(e). %1 %2 hidden. - %1 %2 cachée(e). + %1 %2 cachée(e). xcursor X Cursor - Curseur X + Curseur X X Cursors - Curseurs X + Curseurs X diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 9222b65..d263236 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - %1 %2 tulajdonságainak szerkesztése + %1 %2 tulajdonságainak szerkesztése Name - Név + Név Label content - Címke tartalom + Címke tartalom null - üres + üres name - név + név name + value - név + érték + név + érték + Create new %1 - + Új %1 létrehozása + + Új %1 létrehozása @@ -438,51 +438,51 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter Objects - Tárgyak + Tárgyak Settings - Beállítások + Beállítások History - Előzmények + Előzmények Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. Copied plot screenshot to clipboard! - Ábra képernyőkép vágólapra másolva! + Ábra képernyőkép vágólapra másolva! &Update - &Frissítés + &Frissítés &Update LogarithmPlotter - A LogarithmPlotter &frissítése + A LogarithmPlotter &frissítése @@ -507,23 +507,23 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Hide %1 %2 - %1 %2 elrejtése + %1 %2 elrejtése Show %1 %2 - %1 %2 megjelenítése + %1 %2 megjelenítése Set %1 %2 position - %1 %2 helye beállítása + %1 %2 helye beállítása Delete %1 %2 - %1 %2 törlése + %1 %2 törlése Pick new color for %1 %2 - Válasszon új színt a következőhöz: %1 %2 + Válasszon új színt a következőhöz: %1 %2 @@ -563,7 +563,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Snap to grid - Rácshoz illesztés + Rácshoz illesztés @@ -804,30 +804,30 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. color %1 %2's color changed from %3 to %4. - %1 %2 színe %3-ról %4-re változott. + %1 %2 színe %3-ról %4-re változott. comment Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Példák: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) + A következő paraméterek használatosak, ha a tartomány nem folytonos halmaz. (Példák: ℕ, ℤ, olyan halmazok, mint a {0;3}…) Note: Specify the probability for each value. - Megjegyzés: Adja meg az egyes értékek valószínűségét. + Megjegyzés: Adja meg az egyes értékek valószínűségét. Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … + Megjegyzés: A(z) %1[n] használatával hivatkozhat erre: %1ₙ, a(z) %1[n+1] használatával hivatkozhat erre: %1ₙ₊₁, … If you have latex enabled, you can use use latex markup in between $$ to create equations. - Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. + Ha a LaTeX engedélyezve van, a LaTeX-jelölés használható egyenletek létrehozására $$ között. @@ -846,25 +846,25 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. create New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. delete %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. editproperty %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 of %2 changed from %3 to %4. - %1/%2 megváltozott. Régi érték: %3, új érték: %4. + %1/%2 megváltozott. Régi érték: %3, új érték: %4. @@ -931,11 +931,11 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Function definition is not permitted. - A függvény meghatározása nem engedélyezett. + A függvény meghatározása nem engedélyezett. Expected variable for assignment. - A hozzárendeléshez várt változó. + A hozzárendeléshez várt változó. @@ -1080,53 +1080,53 @@ Kiértékelt kifejezés: %3 function Function - Függvény + Függvény Functions - Függvények + Függvények gainbode Bode Magnitude - Bode-nagyságrend + Bode-nagyságrend Bode Magnitudes - Bode-nagyságrendek + Bode-nagyságrendek low-pass - aluláteresztő + aluláteresztő high-pass - felüláteresztő + felüláteresztő historylib New %1 %2 created. - Új %1 %2 létrehozva. + Új %1 %2 létrehozva. %1 %2 deleted. - %1 %2 törölve. + %1 %2 törölve. %1 of %2 %3 changed from "%4" to "%5". - %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. + %1/%2 %3 megváltozott. Régi érték: %4, új érték: %5. %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. @@ -1237,289 +1237,289 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents name %1 %2 renamed to %3. - %1 %2 átnevezve erre: %3. + %1 %2 átnevezve erre: %3. parameters above - ↑ Felett + ↑ Felett below - ↓ Alatt + ↓ Alatt left - ← Balra + ← Balra right - → Jobbra + → Jobbra above-left - ↖ Felett, balra + ↖ Felett, balra above-right - ↗ Felett, jobbra + ↗ Felett, jobbra below-left - ↙ Alatt, balra + ↙ Alatt, balra below-right - ↘ Alatt, jobbra + ↘ Alatt, jobbra center - >|< Középre + >|< Középre top - ↑ Felső + ↑ Felső bottom - ↓ Alsó + ↓ Alsó top-left - ↖ Bal felső + ↖ Bal felső top-right - ↗ Jobb felső + ↗ Jobb felső bottom-left - ↙ Bal alsó + ↙ Bal alsó bottom-right - ↘ Jobb alsó + ↘ Jobb alsó application - Alkalmazás + Alkalmazás function - Függvény + Függvény high - Magas + Magas low - Alul + Alul Next to target - Cél mellé + Cél mellé With label - Címkével + Címkével Hidden - Rejtett + Rejtett phasebode Bode Phase - Bode-fázis + Bode-fázis Bode Phases - Bode-fázisok + Bode-fázisok point Point - Pont + Pont Points - Pontok + Pontok position Position of %1 %2 set from "%3" to "%4". - %1 %2 áthelyezve innen: „%3” ide: „%4”. + %1 %2 áthelyezve innen: „%3” ide: „%4”. Position of %1 set from %2 to %3. - %1 áthelyezve innen: %2 ide: %3. + %1 áthelyezve innen: %2 ide: %3. prop expression - Kifejezés + Kifejezés definitionDomain - Abszcissza tartomány + Abszcissza tartomány destinationDomain - Ordináta tartomány + Ordináta tartomány labelPosition - Címke helyzete + Címke helyzete displayMode - Megjelenítési mód + Megjelenítési mód labelX - Címke X helyzete + Címke X helyzete drawPoints - Pontok megjelenítése + Pontok megjelenítése drawDashedLines - Szaggatott vonalak megjelenítése + Szaggatott vonalak megjelenítése om_0 - ω₀ + ω₀ pass - Áteresztő + Áteresztő gain - Nagyságrend nyeresége + Nagyságrend nyeresége omGraduation - ω₀ érettségi megjelenítése + ω₀ érettségi megjelenítése phase - Fázis + Fázis unit - Egység használata + Egység használata x - X + X y - Y + Y pointStyle - Pontstílus + Pontstílus probabilities - Valószínűségek listája + Valószínűségek listája text - Tartalom + Tartalom disableLatex - LaTeX-megjelenítés letiltása ennél a szövegnél + LaTeX-megjelenítés letiltása ennél a szövegnél targetElement - Tárgycél + Tárgycél approximate - Hozzávetőleges érték megjelenítése + Hozzávetőleges érték megjelenítése rounding - Kerekítés + Kerekítés displayStyle - Megjelenítési stílus + Megjelenítési stílus targetValuePosition - Cél értékpozíciója + Cél értékpozíciója defaultExpression - Alapértelmezett kifejezés + Alapértelmezett kifejezés baseValues - Kezdeményezési értékek + Kezdeményezési értékek repartition Repartition - Elosztás + Elosztás Repartition functions - Elosztási függvények + Elosztási függvények sequence Sequence - Sorozat + Sorozat Sequences - Sorozatok + Sorozatok sommegainsbode Bode Magnitudes Sum - Bode-nagyságrendek összege + Bode-nagyságrendek összege sommephasesbode Bode Phases Sum - Bode-fázisok összege + Bode-fázisok összege text Text - Szöveg + Szöveg Texts - Szövegek + Szövegek @@ -1587,22 +1587,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents visibility %1 %2 shown. - %1 %2 megjelenítve. + %1 %2 megjelenítve. %1 %2 hidden. - %1 %2 rejtve. + %1 %2 rejtve. xcursor X Cursor - X kurzor + X kurzor X Cursors - X kurzorok + X kurzorok diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index faeb53b..369aa32 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -260,31 +260,31 @@ EditorDialog Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 @@ -438,51 +438,51 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.LogarithmPlotter Objects - Objekter + Objekter Settings - Innstillinger + Innstillinger History - Historikk + Historikk Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». Copied plot screenshot to clipboard! - Kopierte plott-skjermavbildning til utklippstavlen! + Kopierte plott-skjermavbildning til utklippstavlen! &Update - &Oppdater + &Oppdater &Update LogarithmPlotter - &Installer ny versjon av LogartimePlotter + &Installer ny versjon av LogartimePlotter @@ -507,11 +507,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position @@ -519,11 +519,11 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 @@ -563,7 +563,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Snap to grid - Fest til rutenett + Fest til rutenett @@ -1029,53 +1029,53 @@ Evaluated expression: %3 function Function - Funksjon + Funksjon Functions - Funksjoner + Funksjoner gainbode Bode Magnitude - Bode-magnitude + Bode-magnitude Bode Magnitudes - Bode-magnituder + Bode-magnituder low-pass - lavpass + lavpass high-pass - høypass + høypass historylib New %1 %2 created. - Ny %1 %2 opprettet. + Ny %1 %2 opprettet. %1 %2 deleted. - %1 %2 slettet. + %1 %2 slettet. %1 of %2 %3 changed from "%4" to "%5". - %1 av %2 %3 endret fra «%4» til «%5». + %1 av %2 %3 endret fra «%4» til «%5». %1 %2 shown. - %1 %2 vist. + %1 %2 vist. %1 %2 hidden. - %1 %2 skjult. + %1 %2 skjult. @@ -1177,40 +1177,40 @@ Please make sure your latex installation is correct and report a bug if so.phasebode Bode Phase - Bode-fase + Bode-fase Bode Phases - Bode-faser + Bode-faser point Point - Punkt + Punkt Points - Punkter + Punkter repartition Repartition - Distribusjon + Distribusjon Repartition functions - Distribusjonsfunksjoner + Distribusjonsfunksjoner sequence Sequence - Følge + Følge Sequences @@ -1221,25 +1221,25 @@ Please make sure your latex installation is correct and report a bug if so.sommegainsbode Bode Magnitudes Sum - Bode-magnitudesum + Bode-magnitudesum sommephasesbode Bode Phases Sum - Bode-fasesum + Bode-fasesum text Text - Tekst + Tekst Texts - Tekster + Tekster From 5f8c756dc73cb6c94925e51e49d01f8bfb607ff5 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 1 Apr 2024 23:48:57 +0200 Subject: [PATCH 187/436] Enforcing type safety at import. --- .../LogarithmPlotter/js/history/common.mjs | 4 +- .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 3 +- .../LogarithmPlotter/js/lib/qmlpolyfills.mjs | 2 + .../LogarithmPlotter/js/objs/common.mjs | 62 ++-- .../LogarithmPlotter/js/objs/function.mjs | 10 +- .../LogarithmPlotter/js/objs/repartition.mjs | 18 +- .../LogarithmPlotter/js/objs/sequence.mjs | 1 - .../ad5001/LogarithmPlotter/js/objs/text.mjs | 2 +- .../LogarithmPlotter/js/objs/xcursor.mjs | 4 +- .../ad5001/LogarithmPlotter/js/parameters.mjs | 276 +++++++++++++++++- 10 files changed, 327 insertions(+), 55 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs index 66d35fd..229a294 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/history/common.mjs @@ -36,7 +36,7 @@ class HistoryCommonAPI extends Module { redo() { this.history.redo() } clear() { this.history.clear() } addToHistory(action) { this.history.addToHistory(action) } - unserialize(data) { this.history.unserialize(data) } + unserialize(...data) { this.history.unserialize(...data) } serialize() { return this.history.serialize() } } @@ -124,7 +124,7 @@ export class Action { } /** - * Returns a string with the HTML-formated description of the action. + * Returns a string with the HTML-formatted description of the action. * * @returns {string} */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs index fe87ad8..f9fde47 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -129,7 +129,8 @@ class IOAPI extends Module { if(Object.keys(Modules.Objects.types).indexOf(objType) > -1) { Modules.Objects.currentObjects[objType] = [] for(let objData of data['objects'][objType]) { - let obj = new Modules.Objects.types[objType](...objData) + /** @type {DrawableObject} */ + let obj = Modules.Objects.types[objType].import(...objData) Modules.Objects.currentObjects[objType].push(obj) Modules.Objects.currentObjectsByName[obj.name] = obj } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs index 5302aca..bf0661e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/lib/qmlpolyfills.mjs @@ -26,6 +26,8 @@ qsTranslate = qsTranslate || function(category, string) { throw new Error('qsTra qsTr = qsTr || function(string) { throw new Error('qsTr not implemented.'); } /** @type {function(string, string): string} */ QT_TRANSLATE_NOOP = QT_TRANSLATE_NOOP || function(string, string) { throw new Error('QT_TRANSLATE_NOOP not implemented.'); } +/** @type {function(string): string} */ +QT_TR_NOOP = QT_TR_NOOP || function(string) { throw new Error('QT_TR_NOOP not implemented.'); } /** @type {function(string|boolean|int): string} */ String.prototype.arg = String.prototype.arg || function(parameter) { throw new Error('arg not implemented.'); } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index 5fb31ba..c38b5c1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -20,6 +20,7 @@ import { getRandomColor, textsub } from "../utils.mjs" import Objects from "../objects.mjs" import Latex from "../math/latex.mjs" import {Module} from "../modules.mjs" +import {ensureTypeSafety, serializesByPropertyType} from "../parameters.mjs" // This file contains the default data to be imported from all other objects @@ -34,7 +35,7 @@ class ObjectsCommonAPI extends Module { } /** - * Creates a new name for an object, based on the \c allowedLetters. + * Creates a new name for an object, based on the allowedLetters. * If variables with each of the allowedLetters is created, a subscript * number is added to the name. * @param {string} allowedLetters @@ -56,7 +57,7 @@ class ObjectsCommonAPI extends Module { } /** - * Registers the object \c obj in the object list. + * Registers the object obj in the object list. * @param {DrawableObject} obj - Object to be registered. */ registerObject(obj) { @@ -131,6 +132,22 @@ export class DrawableObject { * @return {boolean} */ static executable() {return false} + + /** + * Imports the object from its serialized form. + * @return {DrawableObject} + */ + static import(name, visible, color, labelContent, ...args) { + let importedArgs = [name.toString(), visible === true, color.toString(), labelContent] + console.log('---') + console.log(this, name, args) + for(let [name, propType] of Object.entries(this.properties())) + if(!name.startsWith('comment')) { + console.log(name, propType, importedArgs.length-4, args[importedArgs.length-4]) + importedArgs.push(ensureTypeSafety(propType, args[importedArgs.length-4])) + } + return new this(...importedArgs) + } /** * Base constructor for the object. @@ -138,7 +155,7 @@ export class DrawableObject { * @param {boolean} visible - true if the object is visible, false otherwise. * @param {color|string} color - Color of the object (can be string or QColor) * @param {Enum} labelContent - One of 'null', 'name' or 'name + value' describing the content of the label. - * @constructor() + * @constructor */ constructor(name, visible = true, color = null, labelContent = 'name + value') { if(color == null) color = getRandomColor() @@ -150,15 +167,18 @@ export class DrawableObject { this.requiredBy = [] this.requires = [] } - + /** - * Serilizes the object in an array that can be JSON serialized. + * Serializes the object in an array that can be JSON serialized. * These parameters will be re-entered in the constructor when restored. * @return {array} */ export() { - // Should return what will be inputed as arguments when a file is loaded (serializable form) - return [this.name, this.visible, this.color.toString(), this.labelContent] + let exportList = [this.name, this.visible, this.color.toString(), this.labelContent] + for(let [name, propType] of Object.entries(this.constructor.properties())) + if(!name.startsWith('comment')) + exportList.push(serializesByPropertyType(propType, this[name])) + return exportList } /** @@ -182,7 +202,7 @@ export class DrawableObject { } /** - * Readable string content of the label depending on the value of the \c latexContent. + * Readable string content of the label depending on the value of the latexContent. * @return {string} */ getLabel() { @@ -198,7 +218,7 @@ export class DrawableObject { } /** - * Latex markup string content of the label depending on the value of the \c latexContent. + * Latex markup string content of the label depending on the value of the latexContent. * Every non latin character should be passed as latex symbols and formulas * should be in latex form. * See ../latex.mjs for helper methods. @@ -275,16 +295,15 @@ export class DrawableObject { } /** - * Abstract method. Draw the object onto the \c canvas with the. + * Abstract method. Draw the object onto the canvas with the. * @param {CanvasAPI} canvas - * @param {CanvasRenderingContext2D} ctx */ draw(canvas) {} /** - * Applicates a \c drawFunction with two position arguments depending on - * both the \c posX and \c posY of where the label should be displayed, - * and the \c labelPosition which declares the label should be displayed + * Applicates a drawFunction with two position arguments depending on + * both the posX and posY of where the label should be displayed, + * and the labelPosition which declares the label should be displayed * relatively to that position. * * @param {string|Enum} labelPosition - Position of the label relative to the marked position @@ -333,17 +352,16 @@ export class DrawableObject { } /** - * Automatically draw text (by default the label of the object on the \c canvas with - * the 2D context \c ctx depending on user settings. - * This method takes into account both the \c posX and \c posY of where the label - * should be displayed, including the \c labelPosition relative to it. - * The text is get both through the \c getLatexFunction and \c getTextFunction + * Automatically draw text (by default the label of the object on the canvas + * depending on user settings. + * This method takes into account both the posX and posY of where the label + * should be displayed, including the labelPosition relative to it. + * The text is get both through the getLatexFunction and getTextFunction * depending on whether to use latex. - * Then, it's displayed using the \c drawFunctionLatex (x,y,imageData) and - * \c drawFunctionText (x,y,text) depending on whether to use latex. + * Then, it's displayed using the drawFunctionLatex (x,y,imageData) and + * drawFunctionText (x,y,text) depending on whether to use latex. * * @param {CanvasAPI} canvas - * @param {CanvasRenderingContext2D} ctx * @param {string|Enum} labelPosition - Position of the label relative to the marked position * @param {number} posX - Component of the marked position on the x-axis * @param {number} posY - Component of the marked position on the y-axis diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 0d68830..2386a96 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -35,8 +35,8 @@ export default class Function extends ExecutableObject { 'comment', 'Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5}' ), - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','displayMode')]: P.Enum.FunctionDisplayType, + [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', 'comment2': QT_TRANSLATE_NOOP( 'comment', @@ -81,13 +81,13 @@ export default class Function extends ExecutableObject { return `\\begin{array}{l}${Latex.variable(this.name)}(x) = ${this.expression.latexMarkup}\\\\ D_{${this.name}} = ${this.definitionDomain.latexMarkup}\\end{array}` } } - + export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.expression.toEditableString(), this.definitionDomain.toString(), this.destinationDomain.toString(), + return [this.name, this.visible, this.color.toString(), this.labelContent, + this.expression.toEditableString(), this.definitionDomain.toString(), this.destinationDomain.toString(), this.displayMode, this.labelPosition, this.labelX, this.drawPoints, this.drawDashedLines] } - + execute(x = 1) { if(this.definitionDomain.includes(x)) return this.expression.execute(x) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 0bee9a0..6c5245d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -26,21 +26,25 @@ export default class RepartitionFunction extends ExecutableObject { static displayType(){return qsTr('Repartition')} static displayTypeMultiple(){return qsTr('Repartition functions')} static properties() {return { - [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, - [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', 'comment1': QT_TRANSLATE_NOOP( 'comment', 'Note: Specify the probability for each value.' ), - [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'float', /^-?[\d.,]+$/, /^-?[\d.,]+$/, 'P({name_} = ', ') = '), + [QT_TRANSLATE_NOOP('prop','probabilities')]: new P.Dictionary('string', 'double', /^-?[\d.,]+$/, /^-?[\d.,]+$/, 'P({name_} = ', ') = '), + [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, + [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', }} + static import(name, visible, color, labelContent, ...args) { + if(args.length === 5) + // Two legacy values no longer included. + args.shift(); args.shift() + return super.import(name, visible, color, labelContent, ...args) + } constructor(name = null, visible = true, color = null, labelContent = 'name + value', - beginIncluded = true, drawLineEnds = true, probabilities = {'0': '0'}, labelPosition = 'above', labelX = 1) { + probabilities = {'0': '0'}, labelPosition = 'above', labelX = 1) { if(name == null) name = Common.getNewName('XYZUVW', "F_") super(name, visible, color, labelContent) - this.beginIncluded = beginIncluded - this.drawLineEnds = drawLineEnds this.probabilities = probabilities this.labelPosition = labelPosition this.labelX = labelX @@ -49,7 +53,7 @@ export default class RepartitionFunction extends ExecutableObject { export() { return [this.name, this.visible, this.color.toString(), this.labelContent, - this.beginIncluded, this.drawLineEnds, this.probabilities, this.labelPosition, this.labelX] + this.probabilities, this.labelPosition, this.labelX] } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index a7af26f..a2e8673 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -64,7 +64,6 @@ export default class Sequence extends ExecutableObject { update() { console.log('Updating sequence', this.sequence) - console.trace() super.update() if( this.sequence == null || this.baseValues !== this.sequence.baseValues || diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index e3e2ba2..ed62b81 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -32,7 +32,7 @@ export default class Text extends DrawableObject { [QT_TRANSLATE_NOOP('prop','y')]: new P.Expression(), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Positioning, [QT_TRANSLATE_NOOP('prop','text')]: 'string', - 'comment1': QT_TRANSLATE_NOOP( + 'comment1': QT_TRANSLATE_NOOP( 'comment', 'If you have latex enabled, you can use use latex markup in between $$ to create equations.' ), diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 236bd4a..45727dd 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -29,8 +29,8 @@ export default class XCursor extends DrawableObject { static displayType(){return qsTr('X Cursor')} static displayTypeMultiple(){return qsTr('X Cursors')} static properties() {return { - [QT_TRANSLATE_NOOP('prop','x')]: 'Expression', - [QT_TRANSLATE_NOOP('prop','targetElement')]: new P.ObjectType('ExecutableObject'), + [QT_TRANSLATE_NOOP('prop','x')]: new P.Expression(), + [QT_TRANSLATE_NOOP('prop','targetElement')]: new P.ObjectType('ExecutableObject', true), [QT_TRANSLATE_NOOP('prop','labelPosition')]: P.Enum.Position, [QT_TRANSLATE_NOOP('prop','approximate')]: 'boolean', [QT_TRANSLATE_NOOP('prop','rounding')]: 'number', diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 2cf28a3..0427531 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -1,72 +1,204 @@ /** * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. * Copyright (C) 2021-2024 Ad5001 - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +import {parseDomain, Expression as Expr, Domain} from "./mathlib.mjs" -export class Expression { +const NONE = class Empty {} + +let stringValuesValidators = { + 'int': [parseInt, (x) => !isNaN(x)], + 'double': [parseFloat, (x) => !isNaN(x)], + 'string': [(x) => x, () => true] +} +let stringValidatorTypes = Object.keys(stringValuesValidators) + + +class PropertyType { + /** + * Validates if a value corresponds to the current property type, and if so, returns it. + * @param value + * @returns {null|object} + */ + parse(value) { + throw new TypeError(`validate function of ${typeof this} has not been implemented.`) + } + + /** + * Exports the value of this property type. + * @param value + * @returns {string|number|bool|object} + */ + export(value) { + throw new TypeError(`export function of ${typeof this} has not been implemented.`) + } +} + + +export class Expression extends PropertyType { constructor(...variables) { + super() this.type = 'Expression' this.variables = variables } toString() { - return this.variables.length == 0 ? 'Number' : `Expression(${this.variables.join(', ')})` + return this.variables.length === 0 ? 'Number' : `Expression(${this.variables.join(', ')})` + } + + parse(value) { + let result = NONE + if(typeof value == 'string') + try { + result = new Expr(value) + } catch(e) { + // Silently error and return null + console.trace() + console.log(`Error parsing expression ${value}:`) + console.error(e) + } + return result + } + + export(value) { + if(value instanceof Expr) + return value.toEditableString() + else + throw new TypeError(`Exportation error: ${value} is not an expression.`) } } -export class Enum { + +export class Enum extends PropertyType { constructor(...values) { + super() this.type = 'Enum' this.values = values + this.legacyValues = {} this.translatedValues = values.map(x => qsTr(x)) } toString() { - return this.type + return `${this.type}(${this.values.join(', ')})` + } + + parse(value) { + let result = NONE + if(this.values.includes(value)) + result = value + else if(this.legacyValues[value]) + result = this.legacyValues[value] + return result + } + + export(value) { + if(this.values.includes(value)) + return value + else if(this.legacyValues[value]) + return this.legacyValues[value] + else + throw new TypeError(`Exportation error: ${value} not one of ${this.values.join(', ')}.`) } } -export class ObjectType { - constructor(objType) { + +export class ObjectType extends PropertyType { + constructor(objType, allowNull=false) { + super() this.type = 'ObjectType' this.objType = objType + this.allowNull = allowNull } toString() { return this.objType } + + parse(name) { + let result = NONE + if(typeof name == 'string' && name in Modules.Objects.currentObjectsByName) { + let obj = Modules.Objects.currentObjectsByName[name] + if (obj.type === this.objType || (this.objType === 'ExecutableObject' && obj.execute)) { + result = obj + } else { + // Silently error and return null + console.trace() + console.error(new TypeError(`Object ${name} is of not of type ${this.objType}:`)) + } + } else if(this.allowNull && (name == null || name === "null")) + result = null + return result + } + + export(value) { + if(value.type === this.objType || (this.objType === 'ExecutableObject' && value.execute)) + return value + else + throw new TypeError(`Exportation error: ${value} not a ${this.objType}.`) + } } -export class List { + +export class List extends PropertyType { constructor(type, format = /^.+$/, label = '', forbidAdding = false) { + super() // type can be string, int and double. this.type = 'List' this.valueType = type + if(!stringValidatorTypes.includes(this.valueType)) + throw new TypeError(`${this.valueType} must be one of ${stringValidatorTypes.join(', ')}.`) this.format = format this.label = label this.forbidAdding = forbidAdding } toString() { - return this.objType + return `${this.type}(${this.valueType}:${this.format})` + } + + parse(value) { + let result = NONE + if(typeof value == 'object' && value.__proto__ === Array) { + let list = [] + for(let v of value) { + if (this.format.test(v)) { + v = stringValuesValidators[this.valueType][0](v) + if(stringValuesValidators[this.valueType][1](v)) + list.append(v) + } + } + if(list.length === value.length) + result = value + } + return result + } + + export(value) { + if(typeof value == 'object' && value.__proto__ === Array) + return value + else + throw new TypeError(`Exportation error: ${value} not a list.`) + } } -export class Dictionary { + +export class Dictionary extends PropertyType { constructor(type, keyType = 'string', format = /^.+$/, keyFormat = /^.+$/, preKeyLabel = '', postKeyLabel = ': ', forbidAdding = false) { + super() // type & keyType can be string, int and double. this.type = 'Dict' this.valueType = type @@ -77,9 +209,35 @@ export class Dictionary { this.postKeyLabel = postKeyLabel this.forbidAdding = forbidAdding } - + toString() { - return 'Dictionary' + return `${this.type}(${this.keyType}:${this.keyFormat}: ${this.valueType}:${this.format})` + } + + parse(value) { + let result = NONE + if(typeof value == 'object' && value.__proto__ !== Array) { + let dict = [] + for(let [k, v] of Object.entries(value)) { + if (this.format.test(v) && this.keyFormat.test(k)) { + k = stringValuesValidators[this.keyType][0](k) + v = stringValuesValidators[this.valueType][0](v) + if(stringValuesValidators[this.keyType][1](k)) + if(stringValuesValidators[this.valueType][1](v)) + dict[k] = v + } + } + if(Object.keys(dict).length === Object.keys(value).length) + result = value + } + return result + } + + export(value) { + if(typeof value == 'object' && value.__proto__ !== Array) + return value + else + throw new TypeError(`Exportation error: ${value} not a dictionary.`) } } @@ -95,6 +253,14 @@ Enum.Position = new Enum( QT_TR_NOOP('below-left'), QT_TR_NOOP('below-right') ) +Enum.Position.legacyValues = { + 'top': 'above', + 'bottom': 'below', + 'top-left': 'above-left', + 'top-right': 'above-right', + 'bottom-left': 'below-left', + 'bottom-right': 'below-right', +} Enum.Positioning = new Enum( QT_TR_NOOP('center'), @@ -125,4 +291,86 @@ Enum.XCursorValuePosition = new Enum( QT_TR_NOOP('Hidden') ) +/** + * Ensures whether a provided value is of the corresponding type. + * @param {string|PropertyType} propertyType + * @param {string|number|boolean|array|object}value + * @returns {Object} + */ +export function ensureTypeSafety(propertyType, value) { + let result + let error = false + if(typeof propertyType == 'string') + switch(propertyType) { + case 'string': + result = value + error = typeof value !== 'string' + break + case 'number': + result = parseFloat(value) + error = isNaN(result) + break + case 'boolean': + result = value + error = value !== true && value !== false + break + case 'Domain': + try { + error = typeof value !== 'string' + if(!error) + result = parseDomain(value) + } catch(e) { + // Parse domain sometimes returns an empty set when it cannot parse a domain. + // It's okay though, it shouldn't be user parsed value, so returning an empty set + // is okay for a corrupted file, rather than erroring. + console.trace() + console.log(`Error parsing domain ${value}:`) + console.error(e) + error = true + } + break + } + else if(propertyType instanceof PropertyType) { + result = propertyType.parse(value) + error = result === NONE + } else + throw new TypeError(`Importation error: Unknown property type ${propertyType}.`) + if(error) { + console.trace() + throw new TypeError(`Importation error: Couldn't parse ${JSON.stringify(value)} as ${propertyType}.`) + } + return result +} +/** + * Serializes a property by its type to export into JSON. + * @param {string|PropertyType} propertyType + * @param value + * @returns {Object} + */ +export function serializesByPropertyType(propertyType, value) { + let result + if(typeof propertyType == 'string') + switch(propertyType) { + case 'string': + result = value.toString() + break + case 'number': + result = parseFloat(value) + break + case 'boolean': + result = value === true + break + case 'Domain': + if(value instanceof Domain) + result = value.toString() + else + throw new TypeError(`Exportation error: ${value} is not a domain.`) + break + } + else if(propertyType instanceof PropertyType) { + result = propertyType.export(value) + } else + throw new TypeError(`Exportation error: Unknown property type ${propertyType}.`) + return result +} \ No newline at end of file From 781a0f4aae7e5a0ea10d12476a4f99cab1833d8d Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 2 Apr 2024 00:11:56 +0200 Subject: [PATCH 188/436] Enforcing type safety at export --- .../qml/eu/ad5001/LogarithmPlotter/js/io.mjs | 22 +++++++++---------- .../LogarithmPlotter/js/objs/common.mjs | 4 +--- .../LogarithmPlotter/js/objs/function.mjs | 6 ----- .../LogarithmPlotter/js/objs/gainbode.mjs | 5 ----- .../LogarithmPlotter/js/objs/phasebode.mjs | 5 ----- .../ad5001/LogarithmPlotter/js/objs/point.mjs | 4 ---- .../LogarithmPlotter/js/objs/repartition.mjs | 13 +++++------ .../LogarithmPlotter/js/objs/sequence.mjs | 6 ----- .../js/objs/sommegainsbode.mjs | 4 ---- .../js/objs/sommephasesbode.mjs | 4 ---- .../ad5001/LogarithmPlotter/js/objs/text.mjs | 4 ---- .../LogarithmPlotter/js/objs/xcursor.mjs | 6 ----- .../ad5001/LogarithmPlotter/js/parameters.mjs | 6 +++-- 13 files changed, 21 insertions(+), 68 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs index f9fde47..396ada8 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/io.mjs @@ -98,15 +98,15 @@ class IOAPI extends Module { Modules.History.clear() // Importing settings this.settings.saveFilename = filename - this.settings.xzoom = data["xzoom"] - this.settings.yzoom = data["yzoom"] - this.settings.xmin = data["xmin"] - this.settings.ymax = data["ymax"] - this.settings.xaxisstep = data["xaxisstep"] - this.settings.yaxisstep = data["yaxisstep"] - this.settings.xlabel = data["xaxislabel"] - this.settings.ylabel = data["yaxislabel"] - this.settings.logscalex = data["logscalex"] + this.settings.xzoom = parseFloat(data["xzoom"]) || 100 + this.settings.yzoom = parseFloat(data["yzoom"]) || 10 + this.settings.xmin = parseFloat(data["xmin"]) || 5/10 + this.settings.ymax = parseFloat(data["ymax"]) || 24 + this.settings.xaxisstep = data["xaxisstep"] || "4" + this.settings.yaxisstep = data["yaxisstep"] || "4" + this.settings.xlabel = data["xaxislabel"] || "" + this.settings.ylabel = data["yaxislabel"] || "" + this.settings.logscalex = data["logscalex"] === true if("showxgrad" in data) this.settings.showxgrad = data["showxgrad"] if("showygrad" in data) @@ -115,8 +115,8 @@ class IOAPI extends Module { this.settings.linewidth = data["linewidth"] if("textsize" in data) this.settings.textsize = data["textsize"] - this.rootElement.height = data["height"] - this.rootElement.width = data["width"] + this.rootElement.height = parseFloat(data["height"]) || 500 + this.rootElement.width = parseFloat(data["width"]) || 1000 // Importing objects Modules.Objects.currentObjects = {} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs index c38b5c1..173aef4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/common.mjs @@ -139,11 +139,9 @@ export class DrawableObject { */ static import(name, visible, color, labelContent, ...args) { let importedArgs = [name.toString(), visible === true, color.toString(), labelContent] - console.log('---') - console.log(this, name, args) + console.log('Importing', this.type(), name, args) for(let [name, propType] of Object.entries(this.properties())) if(!name.startsWith('comment')) { - console.log(name, propType, importedArgs.length-4, args[importedArgs.length-4]) importedArgs.push(ensureTypeSafety(propType, args[importedArgs.length-4])) } return new this(...importedArgs) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs index 2386a96..fb9e93c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/function.mjs @@ -82,12 +82,6 @@ export default class Function extends ExecutableObject { } } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.expression.toEditableString(), this.definitionDomain.toString(), this.destinationDomain.toString(), - this.displayMode, this.labelPosition, this.labelX, this.drawPoints, this.drawDashedLines] - } - execute(x = 1) { if(this.definitionDomain.includes(x)) return this.expression.execute(x) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs index fb0e9cd..a4a6416 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/gainbode.mjs @@ -81,11 +81,6 @@ export default class GainBode extends ExecutableObject { \\end{array}` } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.om_0.name, this.pass.toString(), this.gain.toEditableString(), this.labelPosition, this.labelX, this.omGraduation] - } - execute(x=1) { if(typeof x == 'string') x = executeExpression(x) if((this.pass === 'high' && x < this.om_0.x) || (this.pass === 'low' && x > this.om_0.x)) { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs index 5b32ec5..bee6ee6 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/phasebode.mjs @@ -64,11 +64,6 @@ export default class PhaseBode extends ExecutableObject { this.labelX = labelX } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.om_0.name, this.phase.toEditableString(), this.unit, this.labelPosition, this.labelX] - } - getReadableString() { return `${this.name}: ${this.phase.toString(true)}${this.unit} at ${this.om_0.name} = ${this.om_0.x}` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs index 03de816..f53eb72 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/point.mjs @@ -54,10 +54,6 @@ export default class Point extends DrawableObject { return `${Latex.variable(this.name)} = \\left(${this.x.latexMarkup}, ${this.y.latexMarkup}\\right)` } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.pointStyle] - } - draw(canvas) { let [canvasX, canvasY] = [canvas.x2px(this.x.execute()), canvas.y2px(this.y.execute())] let pointSize = 8+(canvas.linewidth*2) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs index 6c5245d..2dd632d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/repartition.mjs @@ -35,9 +35,12 @@ export default class RepartitionFunction extends ExecutableObject { [QT_TRANSLATE_NOOP('prop','labelX')]: 'number', }} static import(name, visible, color, labelContent, ...args) { - if(args.length === 5) + console.log(args, args.length) + if(args.length === 5) { // Two legacy values no longer included. - args.shift(); args.shift() + args.shift() + args.shift() + } return super.import(name, visible, color, labelContent, ...args) } @@ -51,12 +54,6 @@ export default class RepartitionFunction extends ExecutableObject { this.update() } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.probabilities, this.labelPosition, this.labelX] - } - - getReadableString() { let keys = Object.keys(this.probabilities).sort((a,b) => a-b); let varname = this.name.substring(this.name.indexOf("_")+1) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs index a2e8673..10cb154 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sequence.mjs @@ -55,12 +55,6 @@ export default class Sequence extends ExecutableObject { this.labelX = labelX this.update() } - - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.drawPoints, this.drawDashedLines, this.defaultExpression, this.baseValues, - this.labelPosition, this.labelX] - } update() { console.log('Updating sequence', this.sequence) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs index 947c99f..236c3d4 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommegainsbode.mjs @@ -44,10 +44,6 @@ export default class SommeGainsBode extends ExecutableObject { this.recalculateCache() } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.labelPosition, this.labelX] - } - getReadableString() { return `${this.name} = ${Objects.getObjectsName('Gain Bode').join(' + ')}` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs index 30ad4b0..1483788 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/sommephasesbode.mjs @@ -42,10 +42,6 @@ export default class SommePhasesBode extends ExecutableObject { this.recalculateCache() } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.labelPosition, this.labelX] - } - getReadableString() { return `${this.name} = ${Objects.getObjectsName('Phase Bode').join(' + ')}` } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs index ed62b81..dfd0d27 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/text.mjs @@ -78,10 +78,6 @@ export default class Text extends DrawableObject { return `${Latex.variable(this.name)} = "\\textsf{${this.latexMarkupText()}}"` } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, this.x.toEditableString(), this.y.toEditableString(), this.labelPosition, this.text, this.disableLatex] - } - getLabel() { return this.text } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs index 45727dd..2e3c6e0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/objs/xcursor.mjs @@ -60,12 +60,6 @@ export default class XCursor extends DrawableObject { this.targetValuePosition = targetValuePosition } - export() { - return [this.name, this.visible, this.color.toString(), this.labelContent, - this.x.toEditableString(), this.targetElement == null ? null : this.targetElement.name, this.labelPosition, - this.approximate, this.rounding, this.displayStyle, this.targetValuePosition] - } - getReadableString() { if(this.targetElement == null) return `${this.name} = ${this.x.toString()}` return `${this.name} = ${this.x.toString()}\n${this.getTargetValueLabel()}` diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs index 0427531..72f9dee 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/parameters.mjs @@ -144,8 +144,10 @@ export class ObjectType extends PropertyType { } export(value) { - if(value.type === this.objType || (this.objType === 'ExecutableObject' && value.execute)) - return value + if(value == null && this.allowNull) + return null + else if(value.type === this.objType || (this.objType === 'ExecutableObject' && value.execute)) + return value.name else throw new TypeError(`Exportation error: ${value} not a ${this.objType}.`) } From 665906ecb34244816c81db4f54e2bc71e8b3bcda Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 2 Apr 2024 22:11:54 +0200 Subject: [PATCH 189/436] New preferences panel. --- LogarithmPlotter/i18n/lp_de.ts | 148 +++-- LogarithmPlotter/i18n/lp_en.ts | 156 ++++-- LogarithmPlotter/i18n/lp_es.ts | 462 ++++++++-------- LogarithmPlotter/i18n/lp_fr.ts | 148 +++-- LogarithmPlotter/i18n/lp_hu.ts | 150 +++-- LogarithmPlotter/i18n/lp_nb_NO.ts | 376 +++++++------ LogarithmPlotter/i18n/lp_template.ts | 519 +++++++++--------- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 8 +- .../LogarithmPlotter/LogarithmPlotter.qml | 14 +- .../LogarithmPlotter/Popup/Preferences.qml | 187 +++++++ .../eu/ad5001/LogarithmPlotter/Popup/qmldir | 1 + .../LogarithmPlotter/icons/settings/color.svg | 1 + .../eu/ad5001/LogarithmPlotter/js/autoload.js | 3 +- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 4 + .../LogarithmPlotter/js/setting/common.mjs | 67 +++ .../js/setting/expression.mjs | 54 ++ .../LogarithmPlotter/js/setting/general.mjs | 49 ++ .../ad5001/LogarithmPlotter/js/settings.mjs | 39 ++ 18 files changed, 1504 insertions(+), 882 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml create mode 120000 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 4d9a064..2e8b5fe 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Über LogarithmPlotter @@ -186,6 +186,14 @@ Schließen + + BoolSetting + + + Check for updates on startup + Beim Starten auf Updates prüfen + + Changelog @@ -437,14 +445,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" LogarithmPlotter + Objects Objekte + Settings Einstellungen + History Verlauf @@ -473,14 +484,17 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Geladene Datei '%1'. + Copied plot screenshot to clipboard! Grafik in die Zwischenablage kopiert! + &Update &Aktualisieren + &Update LogarithmPlotter LogarithmPlotter &aktualisieren @@ -599,100 +613,105 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Settings - + X Zoom Zoom auf X - + Y Zoom Zoom auf Y - + Min X Minimum X - + Max Y Maximum Y - + Max X Maximum X - + Min Y Minimum Y - + X Axis Step X-Achsen-Schritt - + Y Axis Step Y-Achsen-Schritt - + Line width Linienbreite - + Text size (px) Textgröße (px) - + X Label Etikett der X-Achse - + Y Label Etikett der Y-Achse - + X Log scale Logarithmische Skala in X - + Show X graduation X-Teilung anzeigen - + Show Y graduation Y-Teilung anzeigen - + Copy to clipboard Kopieren in die Zwischenablage - + Save plot Grafik speichern - + Save plot as Grafik speichern unter - + Load plot Grafik laden + + + Done + Schließen + ThanksTo @@ -790,12 +809,12 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" changelog - + Could not fetch changelog: Server error {}. Changelog konnte nicht geholt werden: Server-Fehler {}. - + Could not fetch update: {}. Changelog konnte nicht geholt werden: {}. @@ -1075,6 +1094,22 @@ Ausdruck analysiert: %3 LogarithmPlotter - Drawing error LogarithmPlotter - Fehler + + Automatically close parenthesises and brackets + Klammern automatisch schließen + + + Enable syntax highlighting + Syntaxhervorhebung einschalten + + + Enable autocompletion + Automatische Vervollständigung einschalten + + + Color Scheme + Syntaktische Färbung + function @@ -1106,6 +1141,21 @@ Ausdruck analysiert: %3 Hochpass + + general + + Check for updates on startup + Beim Starten auf Updates prüfen + + + Reset redo stack automaticly + Wiederherstellen-Stapel automatisch zurücksetzen + + + Enable LaTeX rendering + LaTeX-Rendering aktivieren + + historylib @@ -1136,64 +1186,52 @@ Ausdruck analysiert: %3 io - Objects - Objekte + Objekte - Settings - Einstellungen + Einstellungen - History - Verlauf + Verlauf - Saved plot to '%1'. - Gespeicherte Grafik auf '%1'. + Gespeicherte Grafik auf '%1'. - Loading file '%1'. - Laden der Datei '%1'. + Laden der Datei '%1'. - Unknown object type: %1. - Unbekannter Objekttyp: %1. + Unbekannter Objekttyp: %1. - Invalid file provided. - Ungültige Datei angegeben. + Ungültige Datei angegeben. - Could not save file: - Die Datei konnte nicht gespeichert werden: + Die Datei konnte nicht gespeichert werden: - Loaded file '%1'. - Geladene Datei '%1'. + Geladene Datei '%1'. - Copied plot screenshot to clipboard! - Grafik in die Zwischenablage kopiert! + Grafik in die Zwischenablage kopiert! - &Update - &Aktualisieren + &Aktualisieren - &Update LogarithmPlotter - LogarithmPlotter &aktualisieren + LogarithmPlotter &aktualisieren @@ -1226,7 +1264,7 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1505,6 +1543,14 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Folgen + + settingCategory + + + general + + + sommegainsbode @@ -1533,22 +1579,22 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde update - + An update for LogarithPlotter (v{}) is available. Ein Aktualisierung für LogarithmPlotter (v{}) ist verfügbar. - + No update available. Keine Aktualisierung verfügbar. - + Could not fetch update information: Server error {}. Es konnten keine Aktualisierungsinformationen abgerufen werden: Server-Fehler {}. - + Could not fetch update information: {}. Es konnten keine Aktualisierungsinformationen abgerufen werden:{}. diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index f565fe7..998d124 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter About LogarithmPlotter @@ -186,6 +186,14 @@ Close + + BoolSetting + + + Check for updates on startup + Check for updates on startup + + Changelog @@ -437,14 +445,17 @@ These settings can be changed at any time from the "Settings" menu. LogarithmPlotter + Objects Objects + Settings Settings + History History @@ -473,14 +484,17 @@ These settings can be changed at any time from the "Settings" menu.Loaded file '%1'. + Copied plot screenshot to clipboard! Copied plot screenshot to clipboard! + &Update &Update + &Update LogarithmPlotter &Update LogarithmPlotter @@ -599,100 +613,105 @@ These settings can be changed at any time from the "Settings" menu. Settings - + X Zoom X Zoom - + Y Zoom Y Zoom - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step X Axis Step - + Y Axis Step Y Axis Step - + Line width Line width - + Text size (px) Text size (px) - + X Label X Label - + Y Label Y Label - + X Log scale X Log scale - + Show X graduation Show X graduation - + Show Y graduation Show Y graduation - + Copy to clipboard Copy to clipboard - + Save plot Save plot - + Save plot as Save plot as - + Load plot Open plot + + + Done + Done + ThanksTo @@ -790,12 +809,12 @@ These settings can be changed at any time from the "Settings" menu. changelog - + Could not fetch changelog: Server error {}. Could not fetch changelog: Server error {}. - + Could not fetch update: {}. Could not fetch changelog: {}. @@ -1075,6 +1094,22 @@ Evaluated expression: %3 LogarithmPlotter - Drawing error LogarithmPlotter - Drawing error + + Automatically close parenthesises and brackets + Automatically close parentheses and brackets + + + Enable syntax highlighting + Enable syntax highlighting + + + Enable autocompletion + Enable autocompletion + + + Color Scheme + Color Scheme + function @@ -1106,6 +1141,21 @@ Evaluated expression: %3 high-pass + + general + + Check for updates on startup + Check for updates on startup + + + Reset redo stack automaticly + Reset redo stack automatically + + + Enable LaTeX rendering + Enable LaTeX rendering + + historylib @@ -1136,64 +1186,52 @@ Evaluated expression: %3 io - Objects - Objects + Objects - Settings - Settings + Settings - History - History + History - Saved plot to '%1'. - Saved plot to '%1'. + Saved plot to '%1'. - Loading file '%1'. - Loading file '%1'. + Loading file '%1'. - Unknown object type: %1. - Unknown object type: %1. + Unknown object type: %1. - Invalid file provided. - Invalid file provided. + Invalid file provided. - Could not save file: - Could not save file: + Could not save file: - Loaded file '%1'. - Loaded file '%1'. + Loaded file '%1'. - Copied plot screenshot to clipboard! - Copied plot screenshot to clipboard! + Copied plot screenshot to clipboard! - &Update - &Update + &Update - &Update LogarithmPlotter - &Update LogarithmPlotter + &Update LogarithmPlotter @@ -1226,7 +1264,7 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1505,6 +1543,22 @@ Please make sure your LaTeX installation is correct and report a bug if so.Sequences + + settingCategory + + + general + General + + + editor + Expression Editor + + + default + Default Graph + + sommegainsbode @@ -1533,22 +1587,22 @@ Please make sure your LaTeX installation is correct and report a bug if so. update - + An update for LogarithPlotter (v{}) is available. An update for LogarithmPlotter (v{}) is available. - + No update available. No update available. - + Could not fetch update information: Server error {}. Could not fetch update information: Server error {}. - + Could not fetch update information: {}. Could not fetch update information: {}. diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index c8f4310..ef9e33a 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Sobre LogarithmPlotter @@ -105,27 +105,27 @@ Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + @@ -175,7 +175,7 @@ This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + @@ -183,7 +183,15 @@ Close - + + + + + BoolSetting + + + Check for updates on startup + Comprobación de las actualizaciones al arrancar @@ -191,12 +199,12 @@ Fetching changelog... - + Done - + @@ -205,12 +213,12 @@ + Create new %1 - + Pick on graph - + @@ -218,42 +226,42 @@ Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value - + @@ -261,32 +269,32 @@ Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects - + @@ -294,12 +302,12 @@ Export Logarithm Plot file - + Import Logarithm Plot file - + @@ -307,68 +315,68 @@ Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering - Activar el renderizado de LaTeX + Activar el renderizado de LaTeX Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done - + @@ -376,22 +384,22 @@ These settings can be changed at any time from the "Settings" menu. Filter... - + Redo > - + > Now - + < Undo - + @@ -399,6 +407,39 @@ These settings can be changed at any time from the "Settings" menu. + Add Entry + + + + + LogarithmPlotter + + + Objects + + + + + Settings + + + + + History + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter @@ -407,7 +448,7 @@ These settings can be changed at any time from the "Settings" menu. + Create new: - + @@ -415,12 +456,12 @@ These settings can be changed at any time from the "Settings" menu. Hide all %1 - + Show all %1 - + @@ -428,27 +469,27 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 - + @@ -456,135 +497,140 @@ These settings can be changed at any time from the "Settings" menu. Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) - + Settings - + X Zoom - + - + Y Zoom - + - + Min X - + - + Max Y - + - + Max X - + - + Min Y - + - + X Axis Step - + - + Y Axis Step - + - + Line width - + - + Text size (px) - + - + X Label - + - + Y Label - + - + X Log scale - + - + Show X graduation - + - + Show Y graduation - + - + Copy to clipboard - + - + Save plot - + - + Save plot as - + - + Load plot - + + + + + Done + @@ -592,27 +638,27 @@ These settings can be changed at any time from the "Settings" menu. Thanks and Contributions - LogarithmPlotter - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - + @@ -621,76 +667,76 @@ These settings can be changed at any time from the "Settings" menu. Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - + Github - + Norwegian - + Translations included - + Improve - + changelog - + Could not fetch changelog: Server error {}. - + - + Could not fetch update: {}. - + @@ -702,7 +748,7 @@ These settings can be changed at any time from the "Settings" menu. %1: - + @@ -711,152 +757,152 @@ These settings can be changed at any time from the "Settings" menu. Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - + Illegal escape sequence: %1. - + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + @@ -864,7 +910,7 @@ These settings can be changed at any time from the "Settings" menu. - + @@ -872,7 +918,7 @@ Evaluated expression: %3 %3 Undoing last change. - + @@ -881,7 +927,7 @@ Undoing last change. LogarithmPlotter - Parsing error - + @@ -889,75 +935,27 @@ Undoing last change. %2 Evaluated expression: %3 - + LogarithmPlotter - Drawing error - + - io + general - - Objects - + Check for updates on startup + Comprobación de las actualizaciones al arrancar - - Settings - + Reset redo stack automaticly + Restablecer la pila de rehacer automáticamente - - History - - - - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not save file: - - - - - Loaded file '%1'. - - - - - Copied plot screenshot to clipboard! - - - - - &Update - - - - - &Update LogarithmPlotter - + Enable LaTeX rendering + Activar el renderizado de LaTeX @@ -967,12 +965,12 @@ Evaluated expression: %3 No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + @@ -981,38 +979,46 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - + + + + + settingCategory + + + general + update - + An update for LogarithPlotter (v{}) is available. - + - + No update available. - + - + Could not fetch update information: Server error {}. - + - + Could not fetch update information: {}. - + @@ -1021,7 +1027,7 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 - + @@ -1029,27 +1035,27 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - + diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index f9671dc..40a761b 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter À propos de LogarithmPlotter @@ -187,6 +187,14 @@ Fermer + + BoolSetting + + + Check for updates on startup + Vérifier la présence de mise à jour au démarrage + + Changelog @@ -445,14 +453,17 @@ These settings can always be changed at any time from the "Settings" m LogarithmPlotter + Objects Objets + Settings Paramètres + History Historique @@ -481,14 +492,17 @@ These settings can always be changed at any time from the "Settings" m Fichier '%1' chargé. + Copied plot screenshot to clipboard! Image du graphe copiée dans le presse-papiers ! + &Update &Mise à jour + &Update LogarithmPlotter &Mettre à jour LogarithmPlotter @@ -607,100 +621,105 @@ These settings can always be changed at any time from the "Settings" m Settings - + X Zoom Zoom en X - + Y Zoom Zoom en Y - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step Pas de l'axe X - + Y Axis Step Pas de l'axe Y - + Line width Taille des lignes - + Text size (px) Taille du texte (px) - + X Label Label de l'axe X - + Y Label Label de l'axe Y - + X Log scale Échelle logarithmique en X - + Show X graduation Montrer la graduation de l'axe X - + Show Y graduation Montrer la graduation de l'axe Y - + Copy to clipboard Copier vers le presse-papiers - + Save plot Sauvegarder le graphe - + Save plot as Sauvegarder le graphe sous - + Load plot Ouvrir un graphe + + + Done + Fermer + ThanksTo @@ -798,12 +817,12 @@ These settings can always be changed at any time from the "Settings" m changelog - + Could not fetch changelog: Server error {}. Impossible de récupérer l'historique des modifications : Erreur de serveur {}. - + Could not fetch update: {}. Impossible de récupérer l'historique des modifications : {}. @@ -1084,6 +1103,22 @@ Formule analysée : %3 LogarithmPlotter - Drawing error LogarithmPlotter - Erreur + + Automatically close parenthesises and brackets + Fermer automatiquement les parenthèses et les crochets + + + Enable syntax highlighting + Activer la coloration syntaxique + + + Enable autocompletion + Activer l'autocomplétion + + + Color Scheme + Coloration Syntaxique + function @@ -1115,6 +1150,21 @@ Formule analysée : %3 passe-haut + + general + + Check for updates on startup + Vérifier la présence de mise à jour au démarrage + + + Reset redo stack automaticly + Réinitialiser la pile d'action "Rétablir" automatiquement + + + Enable LaTeX rendering + Activer le rendu LaTeX + + historylib @@ -1145,64 +1195,52 @@ Formule analysée : %3 io - Objects - Objets + Objets - Settings - Paramètres + Paramètres - History - Historique + Historique - Saved plot to '%1'. - Graphe sauvegardé dans '%1'. + Graphe sauvegardé dans '%1'. - Loading file '%1'. - Chargement du fichier '%1'. + Chargement du fichier '%1'. - Unknown object type: %1. - Type d'objet inconnu : %1. + Type d'objet inconnu : %1. - Invalid file provided. - Fichier fourni invalide. + Fichier fourni invalide. - Could not save file: - Impossible de sauvegarder le fichier : + Impossible de sauvegarder le fichier : - Loaded file '%1'. - Fichier '%1' chargé. + Fichier '%1' chargé. - Copied plot screenshot to clipboard! - Image du graphe copiée dans le presse-papiers ! + Image du graphe copiée dans le presse-papiers ! - &Update - &Mise à jour + &Mise à jour - &Update LogarithmPlotter - &Mettre à jour LogarithmPlotter + &Mettre à jour LogarithmPlotter @@ -1235,7 +1273,7 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1514,6 +1552,14 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Suites + + settingCategory + + + general + + + sommegainsbode @@ -1542,22 +1588,22 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c update - + An update for LogarithPlotter (v{}) is available. Une mise à jour de LogarithmPlotter (v{}) est disponible. - + No update available. À jour. - + Could not fetch update information: Server error {}. Impossible de récupérer les informations de mise à jour. Erreur du serveur {}. - + Could not fetch update information: {}. Impossible de récupérer les informations de mise à jour. {}. diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index d263236..34f6fc4 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter LogarithmPlotter névjegye @@ -186,6 +186,14 @@ Bezárás + + BoolSetting + + + Check for updates on startup + Frissítések keresése indításkor + + Changelog @@ -437,14 +445,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. LogarithmPlotter + Objects Tárgyak + Settings Beállítások + History Előzmények @@ -473,14 +484,17 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. A(z) „%1” fájl betöltve. + Copied plot screenshot to clipboard! Ábra képernyőkép vágólapra másolva! + &Update &Frissítés + &Update LogarithmPlotter A LogarithmPlotter &frissítése @@ -599,100 +613,105 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Settings - + X Zoom X-nagyítás - + Y Zoom Y-nagyítás - + Min X Legkisebb X - + Max Y Legnagyobb Y - + Max X Legnagyobb X - + Min Y Legkisebb Y - + X Axis Step X tengely lépésköze - + Y Axis Step Y tengely lépésköze - + Line width Vonalvastagság - + Text size (px) Szövegméret (képpont) - + X Label X címke - + Y Label Y címke - + X Log scale X tengely logaritmikus skálával - + Show X graduation X érettségi megjelenítése - + Show Y graduation Y érettségi megjelenítése - + Copy to clipboard Másolás a vágólapra - + Save plot Ábra mentése - + Save plot as Ábra mentése másként - + Load plot Ábra betöltése + + + Done + Kész + ThanksTo @@ -790,12 +809,12 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. changelog - + Could not fetch changelog: Server error {}. Nem sikerült lekérni a változásnaplót: Kiszolgálóhiba: {}. - + Could not fetch update: {}. Nem sikerült lekérni a változásnaplót: {}. @@ -1075,6 +1094,22 @@ Kiértékelt kifejezés: %3 LogarithmPlotter - Drawing error LogarithmPlotter - Rajzolási hiba + + Automatically close parenthesises and brackets + Zárójelek automatikus bezárása + + + Enable syntax highlighting + Mondattani kiemelés engedélyezése + + + Enable autocompletion + Automatikus befejezés engedélyezése + + + Color Scheme + Színséma + function @@ -1106,6 +1141,21 @@ Kiértékelt kifejezés: %3 felüláteresztő + + general + + Check for updates on startup + Frissítések keresése indításkor + + + Reset redo stack automaticly + Ismétlési verem önműködő visszaállítása + + + Enable LaTeX rendering + LaTeX-megjelenítés engedélyezése + + historylib @@ -1132,64 +1182,48 @@ Kiértékelt kifejezés: %3 io - - Objects - - - - Settings - Beállítások + Beállítások - History - Előzmények + Előzmények - Saved plot to '%1'. - Ábra mentve ide: „%1”. + Ábra mentve ide: „%1”. - Loading file '%1'. - A(z) „%1” fájl betöltése folyamatban van. + A(z) „%1” fájl betöltése folyamatban van. - Unknown object type: %1. - Ismeretlen objektumtípus: %1. + Ismeretlen objektumtípus: %1. - Invalid file provided. - A megadott fájl érvénytelen. + A megadott fájl érvénytelen. - Could not save file: - A fájl mentése nem sikerült: + A fájl mentése nem sikerült: - Loaded file '%1'. - A(z) „%1” fájl betöltve. + A(z) „%1” fájl betöltve. - Copied plot screenshot to clipboard! - Ábra képernyőkép vágólapra másolva! + Ábra képernyőkép vágólapra másolva! - &Update - &Frissítés + &Frissítés - &Update LogarithmPlotter - A LogarithmPlotter &frissítése + A LogarithmPlotter &frissítése @@ -1222,7 +1256,7 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1497,6 +1531,14 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents Sorozatok + + settingCategory + + + general + + + sommegainsbode @@ -1525,22 +1567,22 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents update - + An update for LogarithPlotter (v{}) is available. Elérhető a Logaritmus-ábrázoló ({} verzió) frissítése. - + No update available. Nincs telepíthető frissítés. - + Could not fetch update information: Server error {}. Nem sikerült lekérni a frissítési adatokat: Kiszolgálóhiba: {}. - + Could not fetch update information: {}. Nem sikerült lekérni a frissítési adatokat: {}. diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 369aa32..ae1af4e 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -5,7 +5,7 @@ About - + About LogarithmPlotter Om @@ -17,7 +17,7 @@ 2D plotter software to make BODE plots, sequences and repartition functions. - 2D-plotterprogramvare laget for opprettelse av Bode-diagram, sekvenser, og distribusjonsfunksjoner. + 2D-plotterprogramvare laget for opprettelse av Bode-diagram, sekvenser, og distribusjonsfunksjoner. @@ -27,7 +27,7 @@ Official website - + @@ -95,37 +95,37 @@ Reset redo stack automaticly - Tilbakestill angrehistorikk automatisk + Tilbakestill angrehistorikk automatisk Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + @@ -135,32 +135,32 @@ &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + @@ -170,12 +170,12 @@ Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + @@ -183,7 +183,15 @@ Close - + + + + + BoolSetting + + + Check for updates on startup + Se etter nye versjoner ved programstart @@ -191,12 +199,12 @@ Fetching changelog... - + Done - + @@ -205,12 +213,12 @@ + Create new %1 - + Opprett nytt %1 + + Opprett nytt %1 Pick on graph - + @@ -218,42 +226,42 @@ Edit properties of %1 %2 - Rediger egenskaper for %1 %2 + Rediger egenskaper for %1 %2 LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - Navn + Navn Label content - Etikett-innhold + Etikett-innhold null - NULL + NULL name - navn + navn name + value - navn + veri + navn + veri @@ -292,32 +300,32 @@ Object Properties - + Variables - + Constants - + Functions - Funksjoner + Funksjoner Executable Objects - + Objects - Objekter + Objekter @@ -325,7 +333,7 @@ Export Logarithm Plot file - Eksporter logaritmeplott-fil + Eksporter logaritmeplott-fil @@ -365,42 +373,42 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done - + @@ -408,7 +416,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Filter... - + @@ -431,20 +439,23 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + Add Entry - + LogarithmPlotter + Objects Objekter + Settings Innstillinger + History Historikk @@ -473,14 +484,17 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.Lastet inn filen «%1». + Copied plot screenshot to clipboard! Kopierte plott-skjermavbildning til utklippstavlen! + &Update &Oppdater + &Update LogarithmPlotter &Installer ny versjon av LogartimePlotter @@ -531,27 +545,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Hide %1 %2 - Skjul %1 %2 + Skjul %1 %2 Show %1 %2 - Vis %1 %2 + Vis %1 %2 Set %1 %2 position - Sett %1 %2 posisjon + Sett %1 %2 posisjon Delete %1 %2 - Slett %1 %2 + Slett %1 %2 Pick new color for %1 %2 - Velg ny farge for %1 %2 + Velg ny farge for %1 %2 @@ -568,158 +582,163 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) - + Settings - + X Zoom X-forstørrelse - + Y Zoom Y-forstørrelse - + Min X Min. X - + Max Y Maks. Y - + Max X Maks. X - + Min Y Min. Y - + X Axis Step X-aksesteg - + Y Axis Step Y-aksesteg - + Line width Linjebredde - + Text size (px) Tekststørrelse (piksler) - + X Label Navn på X-akse - + Y Label Navn på Y-akse - + X Log scale Logaritmisk skala i x - + Show X graduation - Vis X-inndeling + Vis X-inndeling - + Show Y graduation - Vis Y-inndeling + Vis Y-inndeling - + Copy to clipboard Kopier til utklippstavle - + Save plot Lagre plott - + Save plot as Lagre plott som - + Load plot Last inn plott + + + Done + + ThanksTo Thanks and Contributions - LogarithmPlotter - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - + @@ -728,76 +747,76 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - + Github - + Norwegian - + Translations included - + Improve - + changelog - + Could not fetch changelog: Server error {}. - + - + Could not fetch update: {}. - + @@ -809,7 +828,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. %1: - + @@ -839,152 +858,152 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - + Illegal escape sequence: %1. - + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + @@ -992,7 +1011,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + @@ -1000,7 +1019,7 @@ Evaluated expression: %3 %3 Undoing last change. - + @@ -1009,7 +1028,7 @@ Undoing last change. LogarithmPlotter - Parsing error - + @@ -1017,12 +1036,12 @@ Undoing last change. %2 Evaluated expression: %3 - + LogarithmPlotter - Drawing error - + @@ -1055,6 +1074,17 @@ Evaluated expression: %3 høypass + + general + + Check for updates on startup + Se etter nye versjoner ved programstart + + + Reset redo stack automaticly + Tilbakestill angrehistorikk automatisk + + historylib @@ -1081,64 +1111,52 @@ Evaluated expression: %3 io - Objects - Objekter + Objekter - Settings - Innstillinger + Innstillinger - History - Historikk + Historikk - Saved plot to '%1'. - Lagret plott i «%1». + Lagret plott i «%1». - Loading file '%1'. - Laster inn «%1»-fil. + Laster inn «%1»-fil. - Unknown object type: %1. - Ukjent objekttype: %1. + Ukjent objekttype: %1. - Invalid file provided. - Ugyldig fil angitt. + Ugyldig fil angitt. - Could not save file: - Kunne ikke lagre fil: + Kunne ikke lagre fil: - Loaded file '%1'. - Lastet inn filen «%1». + Lastet inn filen «%1». - Copied plot screenshot to clipboard! - Kopierte plott-skjermavbildning til utklippstavlen! + Kopierte plott-skjermavbildning til utklippstavlen! - &Update - &Oppdater + &Oppdater - &Update LogarithmPlotter - &Installer ny versjon av LogartimePlotter + &Installer ny versjon av LogartimePlotter @@ -1148,12 +1166,12 @@ Evaluated expression: %3 No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + @@ -1162,15 +1180,15 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - + @@ -1217,6 +1235,14 @@ Please make sure your latex installation is correct and report a bug if so.Følger + + settingCategory + + + general + + + sommegainsbode @@ -1245,22 +1271,22 @@ Please make sure your latex installation is correct and report a bug if so. update - + An update for LogarithPlotter (v{}) is available. En ny versjon av LogartimePlotter (v{}) er tilgjengelig - + No update available. Ingen nye versjoner. - + Could not fetch update information: Server error {}. Fant ikke ut om det er noen nye versjoner. Tjenerfeil {}. - + Could not fetch update information: {}. Kunne ikke hente info om hvorvidt det er nye versjoner: {}. @@ -1271,7 +1297,7 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 - + @@ -1279,27 +1305,27 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - + diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 3e4a80b..dcd8d44 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -5,29 +5,29 @@ About - + About LogarithmPlotter - + LogarithmPlotter v%1 - + 2D plotter software to make BODE plots, sequences and repartition functions. - + Report a bug - + Official website - + @@ -35,147 +35,147 @@ &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + &Create - + &Settings - + Check for updates on startup - + Reset redo stack automaticly - + Enable LaTeX rendering - + Expression editor - + Automatically close parenthesises and brackets - + Enable syntax highlighting - + Enable autocompletion - + Color Scheme - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + @@ -183,7 +183,15 @@ Close - + + + + + BoolSetting + + + Check for updates on startup + @@ -191,12 +199,12 @@ Fetching changelog... - + Done - + @@ -205,12 +213,12 @@ + Create new %1 - + Pick on graph - + @@ -218,42 +226,42 @@ Edit properties of %1 %2 - + LogarithmPlotter - Invalid object name - + An object with the name '%1' already exists. - + Name - + Label content - + null - + name - + name + value - + @@ -261,32 +269,32 @@ Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects - + @@ -294,12 +302,12 @@ Export Logarithm Plot file - + Import Logarithm Plot file - + @@ -307,68 +315,68 @@ Welcome to LogarithmPlotter - + Version %1 - + Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - + Check for updates on startup (requires online connectivity) - + Reset redo stack when a new action is added to history - + Enable LaTeX rendering - + Automatically close parenthesises and brackets in expressions - + Enable syntax highlighting for expressions - + Enable autocompletion interface in expression editor - + Color scheme: - + User manual - + Changelog - + Done - + @@ -376,22 +384,22 @@ These settings can be changed at any time from the "Settings" menu. Filter... - + Redo > - + > Now - + < Undo - + @@ -399,6 +407,39 @@ These settings can be changed at any time from the "Settings" menu. + Add Entry + + + + + LogarithmPlotter + + + Objects + + + + + Settings + + + + + History + + + + + Copied plot screenshot to clipboard! + + + + + &Update + + + + + &Update LogarithmPlotter @@ -407,7 +448,7 @@ These settings can be changed at any time from the "Settings" menu. + Create new: - + @@ -415,12 +456,12 @@ These settings can be changed at any time from the "Settings" menu. Hide all %1 - + Show all %1 - + @@ -428,27 +469,27 @@ These settings can be changed at any time from the "Settings" menu. Hide %1 %2 - + Show %1 %2 - + Set %1 %2 position - + Delete %1 %2 - + Pick new color for %1 %2 - + @@ -456,135 +497,140 @@ These settings can be changed at any time from the "Settings" menu. Pointer precision: - + Snap to grid: - + Pick X - + Pick Y - + Open picker settings - + Hide picker settings - + (no pick selected) - + Settings - + X Zoom - + - + Y Zoom - + - + Min X - + - + Max Y - + - + Max X - + - + Min Y - + - + X Axis Step - + - + Y Axis Step - + - + Line width - + - + Text size (px) - + - + X Label - + - + Y Label - + - + X Log scale - + - + Show X graduation - + - + Show Y graduation - + - + Copy to clipboard - + - + Save plot - + - + Save plot as - + - + Load plot - + + + + + Done + @@ -592,27 +638,27 @@ These settings can be changed at any time from the "Settings" menu. Thanks and Contributions - LogarithmPlotter - + Source code - + Original library by Raphael Graf - + Source - + Ported to Javascript by Matthew Crumley - + @@ -621,76 +667,76 @@ These settings can be changed at any time from the "Settings" menu. Website - + Ported to QMLJS by Ad5001 - + Libraries included - + Email - + English - + French - + German - + Hungarian - + Github - + Norwegian - + Translations included - + Improve - + changelog - + Could not fetch changelog: Server error {}. - + - + Could not fetch update: {}. - + @@ -702,7 +748,7 @@ These settings can be changed at any time from the "Settings" menu. %1: - + @@ -711,152 +757,152 @@ These settings can be changed at any time from the "Settings" menu. Cannot find property %1 of object %2. - + Undefined variable %1. - + In order to be executed, object %1 must have at least one argument. - + %1 cannot be executed. - + Invalid expression. - + Invalid expression (parity). - + Unknown character "%1". - + Illegal escape sequence: %1. - + Parse error [%1:%2]: %3 - + Expected %1 - + Unexpected %1 - + Unexpected ".": member access is not permitted - + Unexpected "[]": arrays are disabled. - + Unexpected symbol: %1. - + Function %1 must have at least one argument. - + First argument to map is not a function. - + Second argument to map is not an array. - + First argument to fold is not a function. - + Second argument to fold is not an array. - + First argument to filter is not a function. - + Second argument to filter is not an array. - + Second argument to indexOf is not a string or array. - + Second argument to join is not an array. - + EOF - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. - + @@ -864,7 +910,7 @@ These settings can be changed at any time from the "Settings" menu. - + @@ -872,7 +918,7 @@ Evaluated expression: %3 %3 Undoing last change. - + @@ -881,7 +927,7 @@ Undoing last change. LogarithmPlotter - Parsing error - + @@ -889,75 +935,12 @@ Undoing last change. %2 Evaluated expression: %3 - + LogarithmPlotter - Drawing error - - - - - io - - - Objects - - - - - Settings - - - - - History - - - - - Saved plot to '%1'. - - - - - Loading file '%1'. - - - - - Unknown object type: %1. - - - - - Invalid file provided. - - - - - Could not save file: - - - - - Loaded file '%1'. - - - - - Copied plot screenshot to clipboard! - - - - - &Update - - - - - &Update LogarithmPlotter - + @@ -967,12 +950,12 @@ Evaluated expression: %3 No Latex installation found. If you already have a latex distribution installed, make sure it's installed on your path. Otherwise, you can download a Latex distribution like TeX Live at https://tug.org/texlive/. - + DVIPNG was not found. Make sure you include it from your Latex distribution. - + @@ -981,38 +964,46 @@ Process '{}' ended with a non-zero return code {}: {} Please make sure your latex installation is correct and report a bug if so. - + - + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} Please make sure your latex installation is correct and report a bug if so. - + + + + + settingCategory + + + general + update - + An update for LogarithPlotter (v{}) is available. - + - + No update available. - + - + Could not fetch update information: Server error {}. - + - + Could not fetch update information: {}. - + @@ -1021,7 +1012,7 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 - + @@ -1029,27 +1020,27 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 or %2 - + integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<from: number>, <to: number>, <f: string>, <variable: string>) - + derivative(<f: ExecutableObject>, <x: number>) - + derivative(<f: string>, <variable: string>, <x: number>) - + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 3de96ca..944c18a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -90,13 +90,19 @@ MenuBar { icon.color: enabled ? sysPalette.windowText : sysPaletteIn.windowText enabled: history.redoCount > 0 } - MenuSeparator { } Action { text: qsTr("&Copy plot") shortcut: StandardKey.Copy onTriggered: root.copyDiagramToClipboard() icon.name: 'edit-copy' } + MenuSeparator { } + Action { + text: qsTr("&Preferences") + shortcut: StandardKey.Copy + onTriggered: preferences.open() + icon.name: 'settings' + } } Menu { diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml index 388264c..2e24d53 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogarithmPlotter.qml @@ -55,6 +55,8 @@ ApplicationWindow { Popup.GreetScreen {} + Popup.Preferences {id: preferences} + Popup.Changelog {id: changelog} Popup.About {id: about} @@ -86,19 +88,19 @@ ApplicationWindow { width: parent.width anchors.top: parent.top TabButton { - text: qsTranslate('io', "Objects") + text: qsTr("Objects") icon.name: 'polygon-add-nodes' icon.color: sysPalette.windowText //height: 24 } TabButton { - text: qsTranslate('io', "Settings") + text: qsTr("Settings") icon.name: 'preferences-system-symbolic' icon.color: sysPalette.windowText //height: 24 } TabButton { - text: qsTranslate('io', "History") + text: qsTr("History") icon.name: 'view-history' icon.color: sysPalette.windowText //height: 24 @@ -227,7 +229,7 @@ ApplicationWindow { var file = Helper.gettmpfile() drawCanvas.save(file) Helper.copyImageToClipboard() - alert.show(qsTranslate('io', "Copied plot screenshot to clipboard!")) + alert.show(qsTr("Copied plot screenshot to clipboard!")) } /*! @@ -242,9 +244,9 @@ ApplicationWindow { Menu { id: updateMenu - title: qsTranslate('io', "&Update") + title: qsTr("&Update") Action { - text: qsTranslate('io', "&Update LogarithmPlotter") + text: qsTr("&Update LogarithmPlotter") icon.name: 'update' onTriggered: Qt.openUrlExternally("https://apps.ad5001.eu/logarithmplotter/") } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml new file mode 100644 index 0000000..6218fb9 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -0,0 +1,187 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting +import "../js/setting/common.mjs" as S + +/*! + \qmltype Preferences + \inqmlmodule eu.ad5001.LogarithmPlotter.Popup + \brief Popup to change global application preferences. + + \sa LogarithmPlotter, GreetScreen +*/ +Popup { + id: preferencesPopup + x: (parent.width-width)/2 + y: Math.max(20, (parent.height-height)/2) + width: settingPopupRow.width + 30 + height: settingPopupRow.height + 20 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + // Components for the preferences + Component { + id: boolSettingComponent + + CheckBox { + height: 20 + text: setting.displayName + checked: setting.value() + onClicked: setting.set(this.checked) + } + } + + Component { + id: enumIntSettingComponent + + // Setting when selecting data from an enum, or an object of a certain type. + Setting.ComboBoxSetting { + height: 30 + label: setting.displayName + icon: `settings/${setting.icon}.svg` + currentIndex: setting.value() + model: setting.values() + onActivated: function(newIndex) { setting.set(newIndex) } + } + } + + Row { + id: settingPopupRow + height: 300 + width: categories.width + categorySeparator.width + settingView.width + 70 + spacing: 15 + + anchors { + top: parent.top + bottom: parent.bottom + left: parent.left + right: parent.right + topMargin: 10 + bottomMargin: 10 + rightMargin: 15 + leftMargin: 15 + } + + ColumnLayout { + id: categories + width: 150 + height: parent.height + spacing: 0 + clip: true + + Repeater { + model: Object.keys(Modules.Settings.categories) + + Button { + // width: 150 + Layout.fillWidth: true + text: qsTranslate('settingCategory', modelData) + + onClicked: { + settingList.model = Modules.Settings.categories[modelData] + settingCategoryName.text = text + } + } + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + + Button { + id: closeButton + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + text: qsTr('Done') + onClicked: preferencesPopup.close() + } + } + } + + Rectangle { + id: categorySeparator + anchors { + top: parent.top + topMargin: 5 + } + opacity: 0.3 + color: sysPalette.windowText + height: parent.height - 10 + width: 1 + } + + ScrollView { + id: settingView + clip: true + width: 500 + height: parent.height + + Column { + spacing: 10 + clip: true + width: settingView.width + + Text { + id: settingCategoryName + font.pixelSize: 32 + color: sysPalette.windowText + text: qsTranslate('settingCategory', 'general') + + Rectangle { + id: bottomSeparator + anchors.top: parent.bottom + opacity: 0.3 + color: sysPalette.windowText + width: settingView.width + height: 1 + } + } + + Repeater { + id: settingList + model: Modules.Settings.categories.general + + delegate: Component { + Loader { + width: settingView.width + property var setting: modelData + sourceComponent: { + if(setting instanceof S.BoolSetting) + return boolSettingComponent + else if(setting instanceof S.EnumIntSetting) + return enumIntSettingComponent + else + console.log('Unknown setting type!', modelData.constructor) + } + } + } + } + } + } + } + + Component.onCompleted: open() +} diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir index 9306fae..8c0859f 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/qmldir @@ -8,3 +8,4 @@ GreetScreen 1.0 GreetScreen.qml Changelog 1.0 Changelog.qml ThanksTo 1.0 ThanksTo.qml InsertCharacter 1.0 InsertCharacter.qml +Preferences 1.0 Preferences.qml diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg new file mode 120000 index 0000000..41b711b --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/color.svg @@ -0,0 +1 @@ +../common/appearance.svg \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js index 9f207a0..211aa9e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js @@ -6,4 +6,5 @@ .import "math/latex.mjs" as Latex .import "history/common.mjs" as HistoryCommon .import "canvas.mjs" as CanvasAPI -.import "io.mjs" as IOAPI \ No newline at end of file +.import "io.mjs" as IOAPI +.import "settings.mjs" as SettingsAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index d68bd9d..9649634 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -144,6 +144,10 @@ class CanvasAPI extends Module { // Methods to draw the canvas // + requestPaint() { + this._canvas.requestPaint() + } + /** * Redraws the entire canvas */ diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs new file mode 100644 index 0000000..2e395c6 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs @@ -0,0 +1,67 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class Setting { + constructor(name, nameInConfig, icon) { + this.name = name + this.displayName = qsTr(name) + this.nameInConfig = nameInConfig + this.icon = icon + } + + /** + * Returns the value of the setting. + * @returns {string|boolean|number} + */ + value() { + throw new TypeError(`value of ${this.constructor} not implemented.`) + } + + /** + * Sets the value of the setting + * @param {string|boolean|number} value + */ + set(value) { + throw new TypeError(`value of ${this.constructor} not implemented.`) + } +} + +export class BoolSetting extends Setting { + value() { + return Helper.getSettingBool(this.nameInConfig) + } + + set(value) { + Helper.setSettingBool(this.nameInConfig, value) + } +} + +export class IntSetting extends Setting { + value() { + return Helper.getSettingInt(this.nameInConfig) + } + + set(value) { + Helper.setSettingInt(this.nameInConfig, value) + } +} + +export class EnumIntSetting extends IntSetting { + values() { + throw new TypeError(`enumerations of ${this.constructor} not implemented.`) + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs new file mode 100644 index 0000000..0fab509 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs @@ -0,0 +1,54 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {BoolSetting, EnumIntSetting} from "common.mjs" + +class AutocloseFormula extends BoolSetting { + constructor() { + super(qsTr("Automatically close parenthesises and brackets"), 'expression_editor.autoclose', 'Text') + } +} + +class EnableSyntaxHighlighting extends BoolSetting { + constructor() { + super(qsTr("Enable syntax highlighting"), 'expression_editor.colorize', 'appearance') + } +} + +class EnableAutocomplete extends BoolSetting { + constructor() { + super(qsTr("Enable autocompletion"), 'autocompletion.enabled', 'label') + } +} + +class PickColorScheme extends EnumIntSetting { + constructor() { + super(qsTr("Color Scheme"), 'expression_editor.color_scheme', 'color') + } + + values() { + return ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] + } +} + +export default [ + new AutocloseFormula(), + new EnableAutocomplete(), + new EnableSyntaxHighlighting(), + new PickColorScheme() +] \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs new file mode 100644 index 0000000..2430b52 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs @@ -0,0 +1,49 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {BoolSetting} from "common.mjs" + +class CheckForUpdates extends BoolSetting { + constructor() { + super(QT_TR_NOOP("Check for updates on startup"), 'check_for_updates', 'update') + } +} + +class ResetRedoStack extends BoolSetting { + constructor() { + super(qsTr("Reset redo stack automaticly"), 'reset_redo_stack', 'timeline') + } +} + +class EnableLatex extends BoolSetting { + constructor() { + super(qsTr("Enable LaTeX rendering"), 'enable_latex', 'Expression') + } + + set(value) { + super.set(value) + Modules.Latex.enabled = value + Modules.Canvas.requestPaint() + } +} + +export default [ + new CheckForUpdates(), + new ResetRedoStack(), + new EnableLatex() +] \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs new file mode 100644 index 0000000..8fff543 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs @@ -0,0 +1,39 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +import {Module} from "modules.mjs" +import General from "setting/general.mjs" +import Editor from "setting/expression.mjs" + +class SettingsAPI extends Module { + constructor() { + super('Settings', [ + Modules.Canvas, + Modules.Latex + ]) + + this.categories = { + [QT_TRANSLATE_NOOP('settingCategory', 'general')]: General, + [QT_TRANSLATE_NOOP('settingCategory', 'editor')]: Editor, + [QT_TRANSLATE_NOOP('settingCategory', 'default')]: [], + } + } +} + +/** @type {CanvasAPI} */ +Modules.Settings = Modules.Settings || new SettingsAPI() +export const API = Modules.Settings \ No newline at end of file From fefb0f92b0ac19a63311a539d466c17b8cc9208b Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 2 Apr 2024 22:49:56 +0200 Subject: [PATCH 190/436] New, rewamped Greet Screen. --- LogarithmPlotter/i18n/lp_de.ts | 6 +- LogarithmPlotter/i18n/lp_en.ts | 12 +- LogarithmPlotter/i18n/lp_es.ts | 6 +- LogarithmPlotter/i18n/lp_fr.ts | 6 +- LogarithmPlotter/i18n/lp_hu.ts | 6 +- LogarithmPlotter/i18n/lp_nb_NO.ts | 6 +- LogarithmPlotter/i18n/lp_template.ts | 6 +- .../LogarithmPlotter/Popup/Changelog.qml | 2 +- .../LogarithmPlotter/Popup/GreetScreen.qml | 287 +++++++----------- .../LogarithmPlotter/Popup/Preferences.qml | 4 +- .../LogarithmPlotter/icons/common/close.svg | 48 +++ .../LogarithmPlotter/icons/common/manual.svg | 1 + .../LogarithmPlotter/icons/common/new.svg | 1 + .../LogarithmPlotter/icons/history/delete.svg | 49 +-- 14 files changed, 182 insertions(+), 258 deletions(-) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg mode change 100644 => 120000 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 2e8b5fe..393e01f 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -203,7 +203,7 @@ - Done + Close Schließen @@ -407,7 +407,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - Done + Close Schließen @@ -709,7 +709,7 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" - Done + Close Schließen diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index 998d124..dbc3714 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -203,8 +203,8 @@ - Done - Done + Close + Close @@ -407,8 +407,8 @@ These settings can be changed at any time from the "Settings" menu. - Done - Done + Close + Close @@ -709,8 +709,8 @@ These settings can be changed at any time from the "Settings" menu. - Done - Done + Close + Close diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index ef9e33a..37c6da8 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -203,7 +203,7 @@ - Done + Close @@ -375,7 +375,7 @@ These settings can be changed at any time from the "Settings" menu. - Done + Close @@ -629,7 +629,7 @@ These settings can be changed at any time from the "Settings" menu. - Done + Close diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 40a761b..3dd5482 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -204,7 +204,7 @@ - Done + Close Fermer @@ -399,7 +399,7 @@ Ces paramètres peuvent être modifiés à tout moment à partir du menu "P - Done + Close Fermer @@ -717,7 +717,7 @@ These settings can always be changed at any time from the "Settings" m - Done + Close Fermer diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index 34f6fc4..d9933cc 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -203,7 +203,7 @@ - Done + Close Kész @@ -407,7 +407,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - Done + Close Kész @@ -709,7 +709,7 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - Done + Close Kész diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index ae1af4e..314a690 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -203,7 +203,7 @@ - Done + Close @@ -407,7 +407,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - Done + Close @@ -709,7 +709,7 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - Done + Close diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index dcd8d44..426049e 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -203,7 +203,7 @@ - Done + Close @@ -375,7 +375,7 @@ These settings can be changed at any time from the "Settings" menu. - Done + Close @@ -629,7 +629,7 @@ These settings can be changed at any time from the "Settings" menu. - Done + Close diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml index f86af07..844e22a 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Changelog.qml @@ -96,7 +96,7 @@ Popup { Button { id: doneBtn - text: qsTr("Done") + text: qsTr("Close") font.pixelSize: 18 anchors.bottom: parent.bottom anchors.bottomMargin: 7 diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml index 9ddfa0f..09e16e5 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/GreetScreen.qml @@ -18,6 +18,7 @@ import QtQuick import QtQuick.Controls +import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting /*! \qmltype GreetScreen @@ -32,202 +33,122 @@ Popup { id: greetingPopup x: (parent.width-width)/2 y: Math.max(20, (parent.height-height)/2) - width: Math.max(welcome.width+70, checkForUpdatesSetting.width, resetRedoStackSetting.width)+20 + width: greetingLayout.width+20 height: Math.min(parent.height-40, 700) modal: true focus: true clip: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - ScrollView { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.bottomMargin: bottomButtons.height + 20 - clip: true - - Column { - width: greetingPopup.width - 25 - spacing: 10 - clip: true - topPadding: 35 - - Row { - id: welcome - height: logo.height - spacing: 10 - anchors.horizontalCenter: parent.horizontalCenter - - Image { - id: logo - source: "../icons/logarithmplotter.svg" - sourceSize.width: 48 - sourceSize.height: 48 - width: 48 - height: 48 - } - - Label { - id: welcomeText - anchors.verticalCenter: parent.verticalCenter - wrapMode: Text.WordWrap - font.pixelSize: 32 - text: qsTr("Welcome to LogarithmPlotter") - } - } - - Label { - id: versionText - anchors.horizontalCenter: parent.horizontalCenter - wrapMode: Text.WordWrap - width: implicitWidth - font.pixelSize: 18 - font.italic: true - text: qsTr("Version %1").arg(Helper.getVersion()) - } - - Label { - id: helpText - anchors.horizontalCenter: parent.horizontalCenter - wrapMode: Text.WordWrap - font.pixelSize: 14 - width: parent.width - 50 - text: qsTr("Take a few seconds to configure LogarithmPlotter.\nThese settings can be changed at any time from the \"Settings\" menu.") - } - - CheckBox { - id: checkForUpdatesSetting - anchors.left: parent.left - checked: Helper.getSettingBool("check_for_updates") - text: qsTr('Check for updates on startup (requires online connectivity)') - onClicked: { - Helper.setSettingBool("check_for_updates", checked) - // Set in the menu bar - appMenu.settingsMenu.children[0].checked = checked - } - } - - CheckBox { - id: resetRedoStackSetting - anchors.left: parent.left - checked: Helper.getSettingBool("reset_redo_stack") - text: qsTr('Reset redo stack when a new action is added to history') - onClicked: { - Helper.setSettingBool("reset_redo_stack", checked) - appMenu.settingsMenu.children[1].checked = checked - } - } - - CheckBox { - id: enableLatexSetting - anchors.left: parent.left - checked: Helper.getSettingBool("enable_latex") - text: qsTr('Enable LaTeX rendering') - onClicked: { - Helper.setSettingBool("enable_latex", checked) - appMenu.settingsMenu.children[2].checked = checked - } - } - - CheckBox { - id: autocloseFormulaSetting - anchors.left: parent.left - checked: Helper.getSettingBool("expression_editor.autoclose") - text: qsTr('Automatically close parenthesises and brackets in expressions') - onClicked: { - Helper.setSettingBool("expression_editor.autoclose", checked) - appMenu.settingsMenu.children[3].children[0].checked = checked - } - } - - CheckBox { - id: colorizeFormulaSetting - anchors.left: parent.left - checked: Helper.getSettingBool("expression_editor.colorize") - text: qsTr('Enable syntax highlighting for expressions') - onClicked: { - Helper.setSettingBool("expression_editor.colorize", checked) - appMenu.settingsMenu.children[3].children[1].checked = checked - } - } - - CheckBox { - id: autocompleteFormulaSetting - anchors.left: parent.left - checked: Helper.getSettingBool("autocompletion.enabled") - text: qsTr('Enable autocompletion interface in expression editor') - onClicked: { - Helper.setSettingBool("autocompletion.enabled", checked) - appMenu.settingsMenu.children[3].children[2].checked = checked - } - } - - Row { - anchors.left: parent.left - anchors.leftMargin: 10 - spacing: 10 - - Label { - id: colorSchemeLabel - anchors.verticalCenter: parent.verticalCenter - wrapMode: Text.WordWrap - text: qsTr("Color scheme:") - } - - ComboBox { - model: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] - currentIndex: Helper.getSettingInt("expression_editor.color_scheme") - - onActivated: function(index) { - Helper.setSettingInt("expression_editor.color_scheme", index) - } - } - } - } - } - - Rectangle { - id: bottomSeparator - opacity: 0.3 - color: sysPalette.windowText - width: parent.width * 2 / 3 - height: 1 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: bottomButtons.top - anchors.bottomMargin: 9 - } - - Row { - id: bottomButtons - anchors.bottom: parent.bottom - anchors.bottomMargin: 7 + Column { + id: greetingLayout + width: 600 spacing: 10 - anchors.horizontalCenter: parent.horizontalCenter + clip: true + topPadding: 35 - Button { - id: userManualBtn - text: qsTr("User manual") - font.pixelSize: 18 - onClicked: Qt.openUrlExternally("https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_Sidebar") + Row { + id: welcome + height: logo.height + spacing: 10 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + id: logo + source: "../icons/logarithmplotter.svg" + sourceSize.width: 48 + sourceSize.height: 48 + width: 48 + height: 48 + } + + Label { + id: welcomeText + anchors.verticalCenter: parent.verticalCenter + wrapMode: Text.WordWrap + font.pixelSize: 32 + text: qsTr("Welcome to LogarithmPlotter") + } } - - Button { - id: changelogBtn - text: qsTr("Changelog") + + Label { + id: versionText + anchors.horizontalCenter: parent.horizontalCenter + wrapMode: Text.WordWrap + width: implicitWidth font.pixelSize: 18 - onClicked: changelog.open() - } - - Button { - id: doneBtn - text: qsTr("Done") - font.pixelSize: 18 - onClicked: greetingPopup.close() + font.italic: true + text: qsTr("Version %1").arg(Helper.getVersion()) } } + + Grid { + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: greetingLayout.bottom + anchors.topMargin: 50 + columns: 2 + spacing: 10 + + Repeater { + model: [{ + name: qsTr("Changelog"), + icon: 'common/new.svg', + onClicked: () => changelog.open() + },{ + name: qsTr("Preferences"), + icon: 'common/settings.svg', + onClicked: () => preferences.open() + },{ + name: qsTr("User manual"), + icon: 'common/manual.svg', + onClicked: () => Qt.openUrlExternally("https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_Sidebar") + },{ + name: qsTr("Close"), + icon: 'common/close.svg', + onClicked: () => greetingPopup.close() + }] + + Button { + id: createBtn + width: 96 + height: 96 + onClicked: modelData.onClicked() - Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()) { + Setting.Icon { + id: icon + width: 24 + height: 24 + anchors { + left: parent.left + leftMargin: (parent.width-width)/2 + top: parent.top + topMargin: (label.y-height)/2 + } + color: sysPalette.windowText + source: '../icons/' + modelData.icon + } + + Label { + id: label + anchors { + bottom: parent.bottom + bottomMargin: 5 + left: parent.left + leftMargin: 4 + right: parent.right + rightMargin: 4 + } + horizontalAlignment: Text.AlignHCenter + font.pixelSize: 14 + text: modelData.name + wrapMode: Text.WordWrap + clip: true + } + } + } + } + + Component.onCompleted: if(Helper.getSetting("last_install_greet") != Helper.getVersion()+1) { greetingPopup.open() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index 6218fb9..6f5ac7e 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -115,7 +115,7 @@ Popup { right: parent.right bottom: parent.bottom } - text: qsTr('Done') + text: qsTr('Close') onClicked: preferencesPopup.close() } } @@ -183,5 +183,5 @@ Popup { } } - Component.onCompleted: open() + // Component.onCompleted: open() } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg new file mode 100644 index 0000000..d1bf741 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/close.svg @@ -0,0 +1,48 @@ + + + + + + + + + diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg new file mode 100644 index 0000000..9ca9b8e --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/manual.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg new file mode 100644 index 0000000..7c7f6fd --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/new.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg deleted file mode 100644 index d1bf741..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg new file mode 120000 index 0000000..dca0794 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/history/delete.svg @@ -0,0 +1 @@ +../common/close.svg \ No newline at end of file From 997a1645a0c3fdd7504abd526acebdcd77b94176 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Tue, 2 Apr 2024 22:50:43 +0200 Subject: [PATCH 191/436] Removing Settings submenu. --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 99 ------------------- 1 file changed, 99 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 944c18a..81dbd57 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -127,105 +127,6 @@ MenuBar { } } - Menu { - id: settingsSubMenu - title: qsTr("&Settings") - Action { - id: checkForUpdatesMenuSetting - text: qsTr("Check for updates on startup") - checkable: true - checked: Helper.getSettingBool("check_for_updates") - onTriggered: Helper.setSettingBool("check_for_updates", checked) - icon.name: 'update' - icon.color: sysPalette.buttonText - } - - Action { - id: resetRedoStackMenuSetting - text: qsTr("Reset redo stack automaticly") - checkable: true - checked: Helper.getSettingBool("reset_redo_stack") - onTriggered: Helper.setSettingBool("reset_redo_stack", checked) - icon.name: 'timeline' - icon.color: sysPalette.buttonText - } - - Action { - id: enableLatexJSSetting - text: qsTr("Enable LaTeX rendering") - checkable: true - checked: Helper.getSettingBool("enable_latex") - onTriggered: { - Helper.setSettingBool("enable_latex", checked) - Modules.Latex.enabled = checked - drawCanvas.requestPaint() - } - icon.name: 'Expression' - icon.color: sysPalette.buttonText - } - - Menu { - title: qsTr("Expression editor") - - Action { - id: autocloseFormulaSetting - text: qsTr("Automatically close parenthesises and brackets") - checkable: true - checked: Helper.getSettingBool("expression_editor.autoclose") - onTriggered: { - Helper.setSettingBool("expression_editor.autoclose", checked) - } - icon.name: 'Text' - icon.color: sysPalette.buttonText - } - - Action { - id: colorizeFormulaSetting - text: qsTr("Enable syntax highlighting") - checkable: true - checked: Helper.getSettingBool("expression_editor.colorize") - onTriggered: { - Helper.setSettingBool("expression_editor.colorize", checked) - } - icon.name: 'appearance' - icon.color: sysPalette.buttonText - } - - Action { - id: autocompleteFormulaSetting - text: qsTr("Enable autocompletion") - checkable: true - checked: Helper.getSettingBool("autocompletion.enabled") - onTriggered: { - Helper.setSettingBool("autocompletion.enabled", checked) - } - icon.name: 'label' - icon.color: sysPalette.buttonText - } - - Menu { - id: colorSchemeSetting - title: qsTr("Color Scheme") - property var schemes: ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] - - Repeater { - model: colorSchemeSetting.schemes - - MenuItem { - text: modelData - checkable: true - checked: Helper.getSettingInt("expression_editor.color_scheme") == index - onTriggered: { - parent.children[Helper.getSettingInt("expression_editor.color_scheme")].checked = false - checked = true - Helper.setSettingInt("expression_editor.color_scheme", index) - } - } - } - } - } - } - Menu { title: qsTr("&Help") Action { From 54f980297531a03ea258984951a795e69c69a0ee Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 3 Apr 2024 21:39:06 +0200 Subject: [PATCH 192/436] Adding default canvas settings + Getting rid of Qt5COmpat for Icon. + Fixing some (non production) bugs. --- .../eu/ad5001/LogarithmPlotter/AppMenuBar.qml | 1 - .../LogarithmPlotter/LogGraphCanvas.qml | 41 +++++ .../ObjectLists/Editor/CustomPropertyList.qml | 2 +- .../LogarithmPlotter/Popup/Preferences.qml | 158 +++++++++++++----- .../Setting/ComboBoxSetting.qml | 1 + .../Setting/ExpressionEditor.qml | 20 ++- .../ad5001/LogarithmPlotter/Setting/Icon.qml | 18 +- .../LogarithmPlotter/Setting/TextSetting.qml | 10 +- .../eu/ad5001/LogarithmPlotter/Settings.qml | 37 ++-- .../icons/common/{Text.svg => text.svg} | 0 .../LogarithmPlotter/icons/settings/label.svg | 1 + .../LogarithmPlotter/icons/settings/text.svg | 1 + .../eu/ad5001/LogarithmPlotter/js/autoload.js | 2 +- .../eu/ad5001/LogarithmPlotter/js/canvas.mjs | 13 +- .../js/{settings.mjs => preferences.mjs} | 15 +- .../js/preferences/common.mjs | 137 +++++++++++++++ .../js/preferences/default.mjs | 120 +++++++++++++ .../js/preferences/expression.mjs | 51 ++++++ .../js/{setting => preferences}/general.mjs | 24 +-- .../LogarithmPlotter/js/setting/common.mjs | 67 -------- .../js/setting/expression.mjs | 54 ------ LogarithmPlotter/util/config.py | 15 ++ LogarithmPlotter/util/helper.py | 5 +- 23 files changed, 558 insertions(+), 235 deletions(-) rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/{Text.svg => text.svg} (100%) create mode 120000 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg create mode 120000 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{settings.mjs => preferences.mjs} (74%) create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs create mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs rename LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/{setting => preferences}/general.mjs (75%) delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs delete mode 100644 LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml index 81dbd57..59c7973 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/AppMenuBar.qml @@ -33,7 +33,6 @@ import "js/historylib.mjs" as HistoryLib \sa LogarithmPlotter */ MenuBar { - property var settingsMenu: settingsSubMenu Menu { title: qsTr("&File") diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml index 973142f..fd9a737 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/LogGraphCanvas.qml @@ -168,4 +168,45 @@ Canvas { } }) } + + /*! + \qmlmethod double LogGraphCanvas::x2px(double x) + Converts an \c x coordinate to it's relative position on the canvas. + It supports both logarithmic and non logarithmic scale depending on the currently selected mode. + */ + function x2px(x) { + if(logscalex) { + var logxmin = Math.log(xmin) + return (Math.log(x)-logxmin)*xzoom + } else return (x - xmin)*xzoom + } + + /*! + \qmlmethod double LogGraphCanvas::y2px(double y) + Converts an \c y coordinate to it's relative position on the canvas. + The y axis not supporting logarithmic scale, it only support linear convertion. + */ + function y2px(y) { + return (ymax-y)*yzoom + } + + /*! + \qmlmethod double LogGraphCanvas::px2x(double px) + Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. + It supports both logarithmic and non logarithmic scale depending on the currently selected mode. + */ + function px2x(px) { + if(logscalex) { + return Math.exp(px/xzoom+Math.log(xmin)) + } else return (px/xzoom+xmin) + } + + /*! + \qmlmethod double LogGraphCanvas::px2x(double px) + Converts an x \c px position on the canvas to it's corresponding coordinate on the plot. + It supports both logarithmic and non logarithmic scale depending on the currently selected mode. + */ + function px2y(px) { + return -(px/yzoom-ymax) + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml index a6f57d6..0fd529c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/ObjectLists/Editor/CustomPropertyList.qml @@ -90,7 +90,7 @@ Repeater { root.changed() } } - } + } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index 6f5ac7e..aece6aa 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -20,7 +20,8 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting -import "../js/setting/common.mjs" as S +import "../js/preferences/common.mjs" as S +import "../js/utils.mjs" as Utils /*! \qmltype Preferences @@ -60,11 +61,75 @@ Popup { label: setting.displayName icon: `settings/${setting.icon}.svg` currentIndex: setting.value() - model: setting.values() + model: setting.values onActivated: function(newIndex) { setting.set(newIndex) } } } + Component { + id: stringSettingComponent + + Setting.ComboBoxSetting { + height: 30 + label: setting.displayName + icon: `settings/${setting.icon}.svg` + editable: true + currentIndex: find(setting.value()) + model: setting.defaultValues + onAccepted: function() { + editText = Utils.parseName(editText, false) + if(find(editText) === -1) model.append(editText) + setting.set(editText) + } + onActivated: function(selectedId) { + setting.set(model[selectedId]) + } + Component.onCompleted: editText = setting.value() + } + } + + Component { + id: numberSettingComponent + + Setting.TextSetting { + height: 30 + isDouble: true + label: setting.displayName + min: setting.min() + icon: `settings/${setting.icon}.svg` + value: setting.value() + onChanged: function(newValue) { + if(newValue < setting.max()) + setting.set(newValue) + else { + value = setting.max() + setting.set(setting.max()) + } + } + } + } + + Component { + id: expressionSettingComponent + + Setting.ExpressionEditor { + height: 30 + label: setting.displayName + icon: `settings/${setting.icon}.svg` + defValue: Utils.simplifyExpression(setting.value()) + variables: setting.variables + allowGraphObjects: false + property string propertyName: setting.displayName + onChanged: function(newExpr) { + try { + setting.set(newExpr) + } catch(e) { + errorDialog.showDialog(propertyName, newExpr, e.message) + } + } + } + } + Row { id: settingPopupRow height: 300 @@ -90,7 +155,7 @@ Popup { clip: true Repeater { - model: Object.keys(Modules.Settings.categories) + model: Object.keys(Modules.Preferences.categories) Button { // width: 150 @@ -98,8 +163,8 @@ Popup { text: qsTranslate('settingCategory', modelData) onClicked: { - settingList.model = Modules.Settings.categories[modelData] - settingCategoryName.text = text + settingView.model = Modules.Preferences.categories[modelData] + settingView.name = text } } } @@ -133,50 +198,55 @@ Popup { width: 1 } - ScrollView { + ListView { id: settingView clip: true width: 500 - height: parent.height + spacing: 10 + model: Modules.Preferences.categories.general + anchors { + top: parent.top + bottom: parent.bottom + } + ScrollBar.vertical: ScrollBar { } + property string name: qsTranslate('settingCategory', 'general') + - Column { - spacing: 10 - clip: true - width: settingView.width - - Text { - id: settingCategoryName - font.pixelSize: 32 - color: sysPalette.windowText - text: qsTranslate('settingCategory', 'general') - - Rectangle { - id: bottomSeparator - anchors.top: parent.bottom - opacity: 0.3 - color: sysPalette.windowText - width: settingView.width - height: 1 - } - } + header: Text { + id: settingCategoryName + font.pixelSize: 32 + height: 48 + color: sysPalette.windowText + text: settingView.name - Repeater { - id: settingList - model: Modules.Settings.categories.general - - delegate: Component { - Loader { - width: settingView.width - property var setting: modelData - sourceComponent: { - if(setting instanceof S.BoolSetting) - return boolSettingComponent - else if(setting instanceof S.EnumIntSetting) - return enumIntSettingComponent - else - console.log('Unknown setting type!', modelData.constructor) - } - } + Rectangle { + id: bottomSeparator + anchors.bottom: parent.bottom + anchors.bottomMargin: 8 + opacity: 0.3 + color: sysPalette.windowText + width: settingView.width + height: 1 + } + } + + delegate: Component { + Loader { + width: settingView.width * 2 / 3 + property var setting: modelData + sourceComponent: { + if(setting instanceof S.BoolSetting) + return boolSettingComponent + else if(setting instanceof S.EnumIntSetting) + return enumIntSettingComponent + else if(setting instanceof S.NumberSetting) + return numberSettingComponent + else if(setting instanceof S.ExpressionSetting) + return expressionSettingComponent + else if(setting instanceof S.StringSetting) + return stringSettingComponent + else + console.log('Unknown setting type!', modelData.constructor) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml index d701661..d29ab7c 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ComboBoxSetting.qml @@ -114,6 +114,7 @@ Item { anchors.left: iconLabel.right anchors.leftMargin: icon == "" ? 0 : 5 height: 30 + width: Math.max(85, implicitWidth) anchors.top: parent.top verticalAlignment: TextInput.AlignVCenter text: qsTranslate("control", "%1: ").arg(control.label) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml index ad7e67c..d121781 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/ExpressionEditor.qml @@ -80,6 +80,17 @@ Item { Icon path of the editor. */ property string icon: "" + /*! + \qmlproperty bool ExpressionEditor::allowGraphObjects + If true, allows graph objects to be used as part of the expression. + */ + property bool allowGraphObjects: true + + /*! + \qmlproperty var ExpressionEditor::errorDialog + Allows to summon the error dialog when using additional external parsing. + */ + readonly property alias errorDialog: parsingErrorDialog /*! \qmlproperty string ExpressionEditor::openAndCloseMatches @@ -177,8 +188,9 @@ Item { id: labelItem anchors.left: iconLabel.right anchors.leftMargin: icon == "" ? 0 : 5 - height: parent.height anchors.top: parent.top + height: parent.height + width: Math.max(85, implicitWidth) verticalAlignment: TextInput.AlignVCenter //color: sysPalette.windowText text: visible ? qsTranslate("control", "%1: ").arg(control.label) : "" @@ -380,7 +392,7 @@ Item { id: objectPropertiesList category: qsTr("Object Properties") - visbilityCondition: doesObjectExist + visbilityCondition: control.allowGraphObjects && doesObjectExist itemStartIndex: 0 itemSelected: parent.itemSelected property bool isEnteringProperty: ( @@ -457,7 +469,7 @@ Item { id: executableObjectsList category: qsTr("Executable Objects") - visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot + visbilityCondition: control.allowGraphObjects && parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: functionsList.itemStartIndex + functionsList.model.length itemSelected: parent.itemSelected categoryItems: Modules.Objects.getObjectsName("ExecutableObject").filter(obj => obj != self) @@ -472,7 +484,7 @@ Item { id: objectsList category: qsTr("Objects") - visbilityCondition: parent.currentToken.identifier && !parent.previousToken.dot + visbilityCondition: control.allowGraphObjects && parent.currentToken.identifier && !parent.previousToken.dot itemStartIndex: executableObjectsList.itemStartIndex + executableObjectsList.model.length itemSelected: parent.itemSelected categoryItems: Object.keys(Modules.Objects.currentObjectsByName).filter(obj => obj != self) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml index f845eb9..aeffe53 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/Icon.qml @@ -17,7 +17,7 @@ */ import QtQuick import QtQuick.Window -import Qt5Compat.GraphicalEffects +import QtQuick.Controls.impl /*! \qmltype Icon @@ -41,20 +41,16 @@ Item { \qmlproperty string Icon::source Path of the icon image source. */ - property alias sourceSize: img.sourceSize.width + property alias sourceSize: img.sourceS - Image { + ColorImage { id: img height: parent.height width: parent.width - visible: false - sourceSize.width: width*Screen.devicePixelRatio - sourceSize.height: width*Screen.devicePixelRatio - } - - ColorOverlay { - anchors.fill: img - source: img + // visible: false + property int sourceS: width*Screen.devicePixelRatio + sourceSize.width: sourceS + sourceSize.height: sourceS color: parent.color } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml index d1c4c9d..c795037 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Setting/TextSetting.qml @@ -100,14 +100,14 @@ Item { id: labelItem anchors.left: iconLabel.right anchors.leftMargin: icon == "" ? 0 : 5 - height: parent.height anchors.top: parent.top + height: parent.height + width: Math.max(85, implicitWidth) verticalAlignment: TextInput.AlignVCenter //color: sysPalette.windowText text: visible ? qsTranslate("control", "%1: ").arg(control.label) : "" visible: control.label != "" } - TextField { id: input @@ -128,8 +128,10 @@ Item { onEditingFinished: function() { if(insertButton.focus || insertPopup.focus) return var value = text - if(control.isInt) value = Math.max(control.min,parseInt(value).toString()=="NaN"?control.min:parseInt(value)) - if(control.isDouble) value = Math.max(control.min,parseFloat(value).toString()=="NaN"?control.min:parseFloat(value)) + if(control.isInt) + value = isNaN(parseInt(value)) ? control.min : Math.max(control.min,parseInt(value)) + if(control.isDouble) + value = isNaN(parseFloat(value)) ? control.min : Math.max(control.min,parseFloat(value)) if(value != "" && value.toString() != defValue) { control.changed(value) defValue = value.toString() diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml index cf09695..067c70d 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Settings.qml @@ -44,83 +44,83 @@ ScrollView { Zoom on the x axis of the diagram, provided from settings. \sa Settings */ - property double xzoom: 100 + property double xzoom: Helper.getSettingInt('default_graph.xzoom') /*! \qmlproperty double Settings::yzoom Zoom on the y axis of the diagram, provided from settings. \sa Settings */ - property double yzoom: 10 + property double yzoom: Helper.getSettingInt('default_graph.yzoom') /*! \qmlproperty double Settings::xmin Minimum x of the diagram, provided from settings. \sa Settings */ - property double xmin: 5/10 + property double xmin: Helper.getSettingInt('default_graph.xmin') /*! \qmlproperty double Settings::ymax Maximum y of the diagram, provided from settings. \sa Settings */ - property double ymax: 25 + property double ymax: Helper.getSettingInt('default_graph.ymax') /*! \qmlproperty string Settings::xaxisstep Step of the x axis graduation, provided from settings. \note: Only available in non-logarithmic mode. \sa Settings */ - property string xaxisstep: "4" + property string xaxisstep: Helper.getSetting('default_graph.xaxisstep') /*! \qmlproperty string Settings::yaxisstep Step of the y axis graduation, provided from settings. \sa Settings */ - property string yaxisstep: "4" + property string yaxisstep: Helper.getSetting('default_graph.yaxisstep') /*! \qmlproperty string Settings::xlabel Label used on the x axis, provided from settings. \sa Settings */ - property string xlabel: "" + property string xlabel: Helper.getSetting('default_graph.xlabel') /*! \qmlproperty string Settings::ylabel Label used on the y axis, provided from settings. \sa Settings */ - property string ylabel: "" + property string ylabel: Helper.getSetting('default_graph.ylabel') /*! \qmlproperty double Settings::linewidth Width of lines that will be drawn into the canvas, provided from settings. \sa Settings */ - property double linewidth: 1 + property double linewidth: Helper.getSettingInt('default_graph.linewidth') /*! \qmlproperty double Settings::textsize Font size of the text that will be drawn into the canvas, provided from settings. \sa Settings */ - property double textsize: 18 + property double textsize: Helper.getSettingInt('default_graph.textsize') /*! \qmlproperty bool Settings::logscalex true if the canvas should be in logarithmic mode, false otherwise. Provided from settings. \sa Settings */ - property bool logscalex: true + property bool logscalex: Helper.getSettingBool('default_graph.logscalex') /*! \qmlproperty bool Settings::showxgrad true if the x graduation should be shown, false otherwise. Provided from settings. \sa Settings */ - property bool showxgrad: true + property bool showxgrad: Helper.getSettingBool('default_graph.showxgrad') /*! \qmlproperty bool Settings::showygrad true if the y graduation should be shown, false otherwise. Provided from settings. \sa Settings */ - property bool showygrad: true + property bool showygrad: Helper.getSettingBool('default_graph.showygrad') /*! \qmlproperty bool Settings::saveFilename Path of the currently opened file. Empty if no file is opened. @@ -159,7 +159,7 @@ ScrollView { height: 30 isDouble: true label: qsTr("X Zoom") - min: 1 + min: 0.1 icon: "settings/xzoom.svg" width: settings.settingWidth value: settings.xzoom.toFixed(2) @@ -173,6 +173,7 @@ ScrollView { id: zoomY height: 30 isDouble: true + min: 0.1 label: qsTr("Y Zoom") icon: "settings/yzoom.svg" width: settings.settingWidth @@ -226,10 +227,10 @@ ScrollView { label: qsTr("Max X") icon: "settings/xmax.svg" width: settings.settingWidth - value: Modules.Canvas.px2x(canvas.width).toFixed(2) + defValue: canvas.px2x(canvas.width).toFixed(2) onChanged: function(xvaluemax) { if(xvaluemax > settings.xmin) { - settings.xzoom = settings.xzoom * canvas.width/(Modules.Canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.xzoom = settings.xzoom * canvas.width/(canvas.x2px(xvaluemax)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Maximum x value must be superior to minimum.") @@ -245,10 +246,10 @@ ScrollView { label: qsTr("Min Y") icon: "settings/ymin.svg" width: settings.settingWidth - defValue: Modules.Canvas.px2y(canvas.height).toFixed(2) + defValue: canvas.px2y(canvas.height).toFixed(2) onChanged: function(yvaluemin) { if(yvaluemin < settings.ymax) { - settings.yzoom = settings.yzoom * canvas.height/(Modules.Canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) + settings.yzoom = settings.yzoom * canvas.height/(canvas.y2px(yvaluemin)) // Adjusting zoom to fit. = (end)/(px of current point) settings.changed() } else { alert.show("Minimum y value must be inferior to maximum.") diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/Text.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/text.svg similarity index 100% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/Text.svg rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/common/text.svg diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg new file mode 120000 index 0000000..280f9ad --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/label.svg @@ -0,0 +1 @@ +../common/label.svg \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg new file mode 120000 index 0000000..a705389 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/icons/settings/text.svg @@ -0,0 +1 @@ +../common/text.svg \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js index 211aa9e..5763db0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/autoload.js @@ -7,4 +7,4 @@ .import "history/common.mjs" as HistoryCommon .import "canvas.mjs" as CanvasAPI .import "io.mjs" as IOAPI -.import "settings.mjs" as SettingsAPI \ No newline at end of file +.import "preferences.mjs" as PreferencesAPI \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs index 9649634..cdd0777 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/canvas.mjs @@ -377,10 +377,7 @@ class CanvasAPI extends Module { * @returns {number} */ x2px(x) { - if(this.logscalex) { - let logxmin = Math.log(this.xmin) - return (Math.log(x)-logxmin)*this.xzoom - } else return (x - this.xmin)*this.xzoom + return this._canvas.x2px(x) } /** @@ -390,7 +387,7 @@ class CanvasAPI extends Module { * @returns {number} */ y2px(y) { - return (this.ymax-y)*this.yzoom + return this._canvas.y2px(y) } /** @@ -400,9 +397,7 @@ class CanvasAPI extends Module { * @returns {number} */ px2x(px) { - if(this.logscalex) { - return Math.exp(px/this.xzoom+Math.log(this.xmin)) - } else return (px/this.xzoom+this.xmin) + return this._canvas.px2x(px) } /** @@ -412,7 +407,7 @@ class CanvasAPI extends Module { * @returns {number} */ px2y(px) { - return -(px/this.yzoom-this.ymax) + return this._canvas.px2y(px) } /** diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs similarity index 74% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs index 8fff543..0407ee1 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/settings.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs @@ -16,12 +16,13 @@ * along with this program. If not, see . */ import {Module} from "modules.mjs" -import General from "setting/general.mjs" -import Editor from "setting/expression.mjs" +import General from "preferences/general.mjs" +import Editor from "preferences/expression.mjs" +import DefaultGraph from "preferences/default.mjs" -class SettingsAPI extends Module { +class PreferencesAPI extends Module { constructor() { - super('Settings', [ + super('Preferences', [ Modules.Canvas, Modules.Latex ]) @@ -29,11 +30,11 @@ class SettingsAPI extends Module { this.categories = { [QT_TRANSLATE_NOOP('settingCategory', 'general')]: General, [QT_TRANSLATE_NOOP('settingCategory', 'editor')]: Editor, - [QT_TRANSLATE_NOOP('settingCategory', 'default')]: [], + [QT_TRANSLATE_NOOP('settingCategory', 'default')]: DefaultGraph, } } } /** @type {CanvasAPI} */ -Modules.Settings = Modules.Settings || new SettingsAPI() -export const API = Modules.Settings \ No newline at end of file +Modules.Preferences = Modules.Preferences || new PreferencesAPI() +export const API = Modules.Preferences \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs new file mode 100644 index 0000000..48cd1de --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/common.mjs @@ -0,0 +1,137 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {Expression} from "../mathlib.mjs" + +class Setting { + constructor(type, name, nameInConfig, icon) { + this.type = type + this.name = name + this.displayName = qsTr(name) + this.nameInConfig = nameInConfig + this.icon = icon + } + + /** + * Returns the value of the setting. + * @returns {string|boolean|number} + */ + value() { + throw new TypeError(`value of ${this.constructor} not implemented.`) + } + + /** + * Sets the value of the setting + * @param {string|boolean|number|Expression} value + */ + set(value) { + throw new TypeError(`value of ${this.constructor} not implemented.`) + } + + toString() { + return `Setting<${this.type} ${this.name}>` + } +} + +export class BoolSetting extends Setting { + constructor(name, nameInConfig, icon) { + super('bool', name, nameInConfig, icon) + } + + value() { + return Helper.getSettingBool(this.nameInConfig) + } + + set(value) { + Helper.setSettingBool(this.nameInConfig, value) + } +} + +export class NumberSetting extends Setting { + constructor(name, nameInConfig, icon, min = -Infinity, max = +Infinity) { + super('number', name, nameInConfig, icon) + this.min = typeof min == 'number' ? () => min : min + this.max = typeof max == 'number' ? () => max : max + } + + value() { + return Helper.getSettingInt(this.nameInConfig) + } + + set(value) { + Helper.setSettingInt(this.nameInConfig, value) + } +} + +export class EnumIntSetting extends Setting { + constructor(name, nameInConfig, icon, values = []) { + super('enum', name, nameInConfig, icon) + this.values = values + } + + value() { + return Helper.getSettingInt(this.nameInConfig) + } + + set(value) { + Helper.setSettingInt(this.nameInConfig, value) + } +} + +export class ExpressionSetting extends Setting { + constructor(name, nameInConfig, icon, variables = []) { + super('expression', name, nameInConfig, icon) + this.variables = variables + } + + value() { + return Helper.getSetting(this.nameInConfig) + } + + /** + * + * @param {Expression} value + */ + set(value) { + let vars = value.calc.variables() + if(vars.length === this.variables.length && vars.every(x => this.variables.includes(x))) + Helper.setSetting(this.nameInConfig, value) + else { + let undefinedVars = vars.filter(x => !this.variables.includes(x)) + let allowed = '' + if(this.variables.length > 0) + allowed = `Allowed variables: ${this.variables.join(', ')}.` + throw new TypeError(`Cannot use variable(s) ${undefinedVars.join(', or ')} to define ${this.displayName}. ${allowed}`) + } + } +} + +export class StringSetting extends Setting { + constructor(name, nameInConfig, icon, defaultValues = []) { + super('string', name, nameInConfig, icon) + this.defaultValues = defaultValues + } + + value() { + return Helper.getSetting(this.nameInConfig) + } + + set(value) { + Helper.setSetting(this.nameInConfig, value) + } +} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs new file mode 100644 index 0000000..1546729 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/default.mjs @@ -0,0 +1,120 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {BoolSetting, ExpressionSetting, NumberSetting, StringSetting} from "common.mjs" + + +const XZOOM = new NumberSetting( + QT_TR_NOOP("X Zoom"), + "default_graph.xzoom", + "xzoom", + 0.1 +) + +const YZOOM = new NumberSetting( + QT_TR_NOOP("Y Zoom"), + "default_graph.xzoom", + "yzoom", + 0.1 +) + +const XMIN = new NumberSetting( + QT_TR_NOOP("Min X"), + "default_graph.xmin", + "xmin", + () => Helper.getSettingBool("default_graph.logscalex") ? 1e-100 : -Infinity +) + +const YMAX = new NumberSetting( + QT_TR_NOOP("Max Y"), + "default_graph.ymax", + "ymax" +) + +const XAXISSTEP = new ExpressionSetting( + QT_TR_NOOP("X Axis Step"), + "default_graph.xaxisstep", + "xaxisstep", +) + +const YAXISSTEP = new ExpressionSetting( + QT_TR_NOOP("Y Axis Step"), + "default_graph.yaxisstep", + "yaxisstep", +) + +const LINE_WIDTH = new NumberSetting( + QT_TR_NOOP("Line width"), + "default_graph.linewidth", + "linewidth", + 1 +) + +const TEXT_SIZE = new NumberSetting( + QT_TR_NOOP("Text size (px)"), + "default_graph.textsize", + "textsize" +) + +const X_LABEL = new StringSetting( + QT_TR_NOOP('X Label'), + "default_graph.xlabel", + "xlabel", + ["", "x", "ω (rad/s)"] +) + +const Y_LABEL = new StringSetting( + QT_TR_NOOP('Y Label'), + "default_graph.ylabel", + "xlabel", + ["", "y", "G (dB)", "φ (°)", "φ (deg)", "φ (rad)"] +) + +const LOG_SCALE_X = new BoolSetting( + QT_TR_NOOP('X Log scale'), + "default_graph.logscalex", + "logscalex" +) + +const SHOW_X_GRAD = new BoolSetting( + QT_TR_NOOP('Show X graduation'), + "default_graph.showxgrad", + "showxgrad" +) + +const SHOW_Y_GRAD = new BoolSetting( + QT_TR_NOOP('Show Y graduation'), + "default_graph.showygrad", + "showygrad" +) + +export default [ + XZOOM, + YZOOM, + XMIN, + YMAX, + XAXISSTEP, + YAXISSTEP, + LINE_WIDTH, + TEXT_SIZE, + X_LABEL, + Y_LABEL, + LOG_SCALE_X, + SHOW_X_GRAD, + SHOW_Y_GRAD +] diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs new file mode 100644 index 0000000..92990b8 --- /dev/null +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/expression.mjs @@ -0,0 +1,51 @@ +/** + * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. + * Copyright (C) 2021-2024 Ad5001 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {BoolSetting, EnumIntSetting} from "common.mjs" + +const AUTOCLOSE_FORMULA = new BoolSetting( + QT_TR_NOOP("Automatically close parenthesises and brackets"), + 'expression_editor.autoclose', + 'text' +) + +const ENABLE_SYNTAX_HIGHLIGHTING = new BoolSetting( + QT_TR_NOOP("Enable syntax highlighting"), + 'expression_editor.colorize', + 'appearance' +) + +const ENABLE_AUTOCOMPLETE = new BoolSetting( + QT_TR_NOOP("Enable autocompletion"), + 'autocompletion.enabled', + 'label' +) + +const PICK_COLOR_SCHEME = new EnumIntSetting( + QT_TR_NOOP("Color Scheme"), + 'expression_editor.color_scheme', + 'color', + ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] +) + +export default [ + AUTOCLOSE_FORMULA, + ENABLE_AUTOCOMPLETE, + ENABLE_SYNTAX_HIGHLIGHTING, + PICK_COLOR_SCHEME +] \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs similarity index 75% rename from LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs rename to LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs index 2430b52..0954f67 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/general.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences/general.mjs @@ -18,17 +18,17 @@ import {BoolSetting} from "common.mjs" -class CheckForUpdates extends BoolSetting { - constructor() { - super(QT_TR_NOOP("Check for updates on startup"), 'check_for_updates', 'update') - } -} +const CHECK_FOR_UPDATES = new BoolSetting( + QT_TR_NOOP("Check for updates on startup"), + 'check_for_updates', + 'update' +) -class ResetRedoStack extends BoolSetting { - constructor() { - super(qsTr("Reset redo stack automaticly"), 'reset_redo_stack', 'timeline') - } -} +const RESET_REDO_STACK = new BoolSetting( + QT_TR_NOOP("Reset redo stack automaticly"), + 'reset_redo_stack', + 'timeline' +) class EnableLatex extends BoolSetting { constructor() { @@ -43,7 +43,7 @@ class EnableLatex extends BoolSetting { } export default [ - new CheckForUpdates(), - new ResetRedoStack(), + CHECK_FOR_UPDATES, + RESET_REDO_STACK, new EnableLatex() ] \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs deleted file mode 100644 index 2e395c6..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/common.mjs +++ /dev/null @@ -1,67 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -class Setting { - constructor(name, nameInConfig, icon) { - this.name = name - this.displayName = qsTr(name) - this.nameInConfig = nameInConfig - this.icon = icon - } - - /** - * Returns the value of the setting. - * @returns {string|boolean|number} - */ - value() { - throw new TypeError(`value of ${this.constructor} not implemented.`) - } - - /** - * Sets the value of the setting - * @param {string|boolean|number} value - */ - set(value) { - throw new TypeError(`value of ${this.constructor} not implemented.`) - } -} - -export class BoolSetting extends Setting { - value() { - return Helper.getSettingBool(this.nameInConfig) - } - - set(value) { - Helper.setSettingBool(this.nameInConfig, value) - } -} - -export class IntSetting extends Setting { - value() { - return Helper.getSettingInt(this.nameInConfig) - } - - set(value) { - Helper.setSettingInt(this.nameInConfig, value) - } -} - -export class EnumIntSetting extends IntSetting { - values() { - throw new TypeError(`enumerations of ${this.constructor} not implemented.`) - } -} \ No newline at end of file diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs deleted file mode 100644 index 0fab509..0000000 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/setting/expression.mjs +++ /dev/null @@ -1,54 +0,0 @@ -/** - * LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions. - * Copyright (C) 2021-2024 Ad5001 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import {BoolSetting, EnumIntSetting} from "common.mjs" - -class AutocloseFormula extends BoolSetting { - constructor() { - super(qsTr("Automatically close parenthesises and brackets"), 'expression_editor.autoclose', 'Text') - } -} - -class EnableSyntaxHighlighting extends BoolSetting { - constructor() { - super(qsTr("Enable syntax highlighting"), 'expression_editor.colorize', 'appearance') - } -} - -class EnableAutocomplete extends BoolSetting { - constructor() { - super(qsTr("Enable autocompletion"), 'autocompletion.enabled', 'label') - } -} - -class PickColorScheme extends EnumIntSetting { - constructor() { - super(qsTr("Color Scheme"), 'expression_editor.color_scheme', 'color') - } - - values() { - return ["Breeze Light", "Breeze Dark", "Solarized", "Github Light", "Github Dark", "Nord", "Monokai"] - } -} - -export default [ - new AutocloseFormula(), - new EnableAutocomplete(), - new EnableSyntaxHighlighting(), - new PickColorScheme() -] \ No newline at end of file diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index bdd11b7..5c2c653 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -34,6 +34,21 @@ DEFAULT_SETTINGS = { }, "autocompletion": { "enabled": True + }, + "default_graph": { + "xzoom": 100, + "yzoom": 10, + "xmin": 5/10, + "ymax": 25, + "xaxisstep": "4", + "yaxisstep": "4", + "xlabel": "", + "ylabel": "", + "linewidth": 1, + "textsize": 18, + "logscalex": True, + "showxgrad": True, + "showygrad": True } } diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index e6e9dfb..47e7395 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -129,8 +129,9 @@ class Helper(QObject): def getSetting(self, namespace): return config.getSetting(namespace) - @Slot(str, result=int) + @Slot(str, result=float) def getSettingInt(self, namespace): + print('Getting', namespace, config.getSetting(namespace)) return config.getSetting(namespace) @Slot(str, result=bool) @@ -145,7 +146,7 @@ class Helper(QObject): def setSettingBool(self, namespace, value): return config.setSetting(namespace, value) - @Slot(str, int) + @Slot(str, float) def setSettingInt(self, namespace, value): return config.setSetting(namespace, value) From 915c6b5246f34f63f618e75acfd273cf09194bae Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Wed, 3 Apr 2024 22:05:57 +0200 Subject: [PATCH 193/436] Setting version to v0.6.0 --- LogarithmPlotter/__init__.py | 2 +- mac/Info.plist | 2 +- scripts/package-macosx.sh | 2 +- snapcraft.yaml | 2 +- win/installer.nsi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/LogarithmPlotter/__init__.py b/LogarithmPlotter/__init__.py index d8bb713..9c675a2 100644 --- a/LogarithmPlotter/__init__.py +++ b/LogarithmPlotter/__init__.py @@ -17,7 +17,7 @@ """ from shutil import which -__VERSION__ = "0.5.1" +__VERSION__ = "0.6.0" is_release = False diff --git a/mac/Info.plist b/mac/Info.plist index d7c0c50..1ba304b 100644 --- a/mac/Info.plist +++ b/mac/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.5.0 + 0.6.0 NSHighResolutionCapable UTExportedTypeDeclarations diff --git a/scripts/package-macosx.sh b/scripts/package-macosx.sh index f7e9cbe..745f05b 100644 --- a/scripts/package-macosx.sh +++ b/scripts/package-macosx.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash cd "$(dirname "$(readlink -f "$0" || realpath "$0")")/.." -VERSION=0.5.0 +VERSION=0.6.0 title="LogarithmPlotter v${VERSION} Setup" finalDMGName="LogarithmPlotter-v${VERSION}-setup.dmg" applicationName=LogarithmPlotter diff --git a/snapcraft.yaml b/snapcraft.yaml index c6632f9..e8c8628 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,6 +1,6 @@ name: logarithmplotter title: LogarithmPlotter -version: '0.5.0' +version: '0.6.0' summary: Create and edit Bode plots confinement: strict base: core22 diff --git a/win/installer.nsi b/win/installer.nsi index 7c5b248..58261ff 100644 --- a/win/installer.nsi +++ b/win/installer.nsi @@ -11,7 +11,7 @@ Unicode True !define PROG_ID "LogarithmPlotter.File.1" !define DEV_NAME "Ad5001" !define WEBSITE "https://apps.ad5001.eu/logarithmplotter" -!define VERSION_SHORT "0.5.0" +!define VERSION_SHORT "0.6.0" !define APP_VERSION "${VERSION_SHORT}.0" !define COPYRIGHT "Ad5001 (c) 2021-2024" !define DESCRIPTION "Create graphs with logarithm scales." From 87d8882db10e10f25f1d013a58b875b361f1916a Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Tue, 2 Apr 2024 21:16:37 +0000 Subject: [PATCH 194/436] Translated using Weblate (Spanish) Currently translated at 80.2% (244 of 304 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/es/ --- LogarithmPlotter/i18n/lp_es.ts | 343 +++++++++++++++++++++++++++++---- 1 file changed, 310 insertions(+), 33 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 37c6da8..46b9a2e 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -110,22 +110,22 @@ Automatically close parenthesises and brackets - + Cerrar automáticamente paréntesis y corchetes Enable syntax highlighting - + Activar el resaltado sintáctico Enable autocompletion - + Activar autocompletar Color Scheme - + Esquema de colores @@ -175,7 +175,7 @@ This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? - + Este gráfico contiene cambios sin guardar. Al hacer esto, se perderán todos los datos no guardados. ¿Continuar? @@ -183,7 +183,7 @@ Close - + Cerrar @@ -199,12 +199,12 @@ Fetching changelog... - + Obteniendo el registro de cambios… Close - + Cerrar @@ -213,12 +213,12 @@ + Create new %1 - + + Crear nuevo %1 Pick on graph - + Elegir en el gráfico @@ -226,17 +226,17 @@ Edit properties of %1 %2 - + Editar las propiedades de %1 %2 LogarithmPlotter - Invalid object name - + LogarithmPlotter - Nombre de objeto no válido An object with the name '%1' already exists. - + Ya existe un objeto con el nombre '%1'. @@ -261,7 +261,7 @@ name + value - + nombre + valor @@ -269,7 +269,7 @@ Object Properties - + Propiedades de los objetos @@ -279,12 +279,12 @@ Constants - + Constantes Functions - + Funciones @@ -389,17 +389,17 @@ These settings can be changed at any time from the "Settings" menu. Redo > - + Rehacer > > Now - + > Ahora < Undo - + < Deshacer @@ -415,32 +415,56 @@ These settings can be changed at any time from the "Settings" menu. Objects - + Objetos Settings - + Ajustes History - + Historial Copied plot screenshot to clipboard! - + ¡Captura de pantalla del gráfico copiada al portapapeles! &Update - + &Actualizar &Update LogarithmPlotter - + &Actualizar LogarithmPlotter + + + Unknown object type: %1. + Tipo de objeto desconocido: %1 . + + + Saved plot to '%1'. + Gráfico guardado en '%1'. + + + Loading file '%1'. + Cargando el archivo '%1'. + + + Invalid file provided. + Se ha proporcionado un archivo no válido. + + + Could not save file: + No se ha podido guardar el archivo: + + + Loaded file '%1'. + Archivo cargado '%1'. @@ -463,6 +487,26 @@ These settings can be changed at any time from the "Settings" menu.Show all %1 + + Delete %1 %2 + Borrar %1 %2 + + + Hide %1 %2 + Ocultar %1 %2 + + + Show %1 %2 + Mostrar %1 %2 + + + Set %1 %2 position + Fijar la posición %1 %2 + + + Pick new color for %1 %2 + Elegir nuevo color para %1 %2 + ObjectRow @@ -529,6 +573,10 @@ These settings can be changed at any time from the "Settings" menu.(no pick selected) + + Snap to grid + Ajustar a la cuadrícula + Settings @@ -920,6 +968,14 @@ Evaluated expression: %3 Undoing last change. + + Function definition is not permitted. + No se permite la definición de las funciones. + + + Expected variable for assignment. + Variable de asignación esperada. + expression @@ -1003,22 +1059,22 @@ Please make sure your latex installation is correct and report a bug if so. An update for LogarithPlotter (v{}) is available. - + Una actualización para LogarithmPlotter (v{}) está disponible. No update available. - + No hay ninguna actualización disponible. Could not fetch update information: Server error {}. - + No se ha podido obtener la información de la actualización: Error del servidor {}. Could not fetch update information: {}. - + No se pudo obtener información de la actualización: {}. @@ -1027,7 +1083,7 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 - + Uso: %1 @@ -1035,12 +1091,13 @@ Please make sure your latex installation is correct and report a bug if so. Usage: %1 or %2 - + Uso: %1 o +%2 integral(<from: number>, <to: number>, <f: ExecutableObject>) - + integral(<desde: número>, <hasta: número>, <f: objeto ejecutable>) @@ -1058,4 +1115,224 @@ Please make sure your latex installation is correct and report a bug if so. + + io + + History + Historial + + + Copied plot screenshot to clipboard! + ¡Captura de pantalla del gráfico copiada al portapapeles! + + + &Update + &Actualizar + + + &Update LogarithmPlotter + &Actualizar LogarithmPlotter + + + Settings + Ajustes + + + Objects + Objetos + + + + color + + %1 %2's color changed from %3 to %4. + El color de %1 %2 cambió de %3 a %4. + + + + create + + New %1 %2 created. + Se ha creado un nuevo %1 %2. + + + + editproperty + + %1 of %2 %3 changed from "%4" to "%5". + %1 de %2 %3 cambió de "%4" a "%5". + + + %1 of %2 changed from %3 to %4. + %1 de %2 ha cambiado de %3 a %4. + + + + function + + Function + Función + + + Functions + Funciones + + + + gainbode + + high-pass + Filtro paso alto + + + low-pass + Filtro paso bajo + + + Bode Magnitude + Magnitud de Bode + + + Bode Magnitudes + Magnitudes de Bode + + + + historylib + + %1 %2 deleted. + %1 %2 borrados. + + + %1 %2 shown. + Se muestra %1 %2. + + + %1 %2 hidden. + Se oculta %1 %2. + + + New %1 %2 created. + Se ha creado un nuevo %1 %2. + + + Name of %1 %2 changed to %3. + El nombre de %1 %2 se ha cambiado por %3. + + + %1 of %2 %3 changed from "%4" to "%5". + %1 de %2 %3 cambió de "%4" a "%5". + + + + parameters + + below + ↓ Abajo + + + left + ← Izquierda + + + above-left + ↖ Arriba a la izquierda + + + below-left + ↙ Abajo a la izquierda + + + below-right + ↘ Arriba a la derecha + + + center + >|< Centro + + + top + ↑ Arriba + + + above + ↑ Arriba + + + right + → Derecha + + + above-right + ↗ Arriba a la derecha + + + + EditorDialog + + Label content + Contenido de la etiqueta + + + null + nulo + + + name + nombre + + + name + value + nombre + valor + + + + Create new %1 + + Crear nuevo %1 + + + Edit properties of %1 %2 + Editar propiedades de %1 %2 + + + Name + Nombre + + + + comment + + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Ej: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + + + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) + Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) + + + Note: Specify the probability for each value. + Nota: Especifique la probabilidad para cada valor. + + + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + Nota: Utilice %1[n] para referirse a %1ₙ, %1[n+1] para %1ₙ₊₁… + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + Si tiene habilitado el latex, puede utilizar el marcado de latex entre $$ para crear ecuaciones. + + + + delete + + %1 %2 deleted. + %1 %2 borrados. + + + + name + + %1 %2 renamed to %3. + %1 %2 ha sido renombrado a %3. + + From 136ac4c7bc960fcaeb5bb14c54e6b20a599ff28a Mon Sep 17 00:00:00 2001 From: ovari Date: Sat, 20 Apr 2024 05:46:53 +0000 Subject: [PATCH 195/436] Translated using Weblate (Hungarian) Currently translated at 100.0% (304 of 304 strings) Translation: LogarithmPlotter/LogarithmPlotter Translate-URL: https://hosted.weblate.org/projects/logarithmplotter/logarithmplotter/hu/ --- LogarithmPlotter/i18n/lp_hu.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index d9933cc..a7d3804 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -1178,6 +1178,10 @@ Kiértékelt kifejezés: %3 %1 %2 hidden. %1 %2 rejtve. + + Name of %1 %2 changed to %3. + %1 %2 neve a következőre módosult: %3. + io @@ -1225,6 +1229,10 @@ Kiértékelt kifejezés: %3 &Update LogarithmPlotter A LogarithmPlotter &frissítése + + Objects + Objektumok + latex @@ -1508,6 +1516,10 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents baseValues Kezdeményezési értékek + + color + Szín + repartition @@ -1538,6 +1550,14 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents general + + editor + Kifejezésszerkesztő + + + default + Alapértelmezett ábra + sommegainsbode From 606ec428abfae73f716f78ca9898540cf3a566ea Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 15 Sep 2024 21:30:44 +0200 Subject: [PATCH 196/436] Fixing issue with setting JS objects being serialized into ListViews. + Fixing broken links on Linux --- .../LogarithmPlotter/Popup/Preferences.qml | 23 ++++--- .../LogarithmPlotter/js/preferences.mjs | 2 +- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 66 +++++++++---------- linux/generate-appstream-changelog.sh | 18 ++--- 4 files changed, 54 insertions(+), 55 deletions(-) diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml index aece6aa..9d7b9c0 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/Popup/Preferences.qml @@ -163,8 +163,7 @@ Popup { text: qsTranslate('settingCategory', modelData) onClicked: { - settingView.model = Modules.Preferences.categories[modelData] - settingView.name = text + settingView.modelName = modelData } } } @@ -203,13 +202,13 @@ Popup { clip: true width: 500 spacing: 10 - model: Modules.Preferences.categories.general + model: Modules.Preferences.categories[modelName] anchors { top: parent.top bottom: parent.bottom } ScrollBar.vertical: ScrollBar { } - property string name: qsTranslate('settingCategory', 'general') + property string modelName: 'general' header: Text { @@ -217,7 +216,7 @@ Popup { font.pixelSize: 32 height: 48 color: sysPalette.windowText - text: settingView.name + text: qsTranslate('settingCategory', settingView.modelName) Rectangle { id: bottomSeparator @@ -233,20 +232,20 @@ Popup { delegate: Component { Loader { width: settingView.width * 2 / 3 - property var setting: modelData + property var setting: Modules.Preferences.categories[settingView.modelName][index] sourceComponent: { - if(setting instanceof S.BoolSetting) + if(setting.type === "bool") return boolSettingComponent - else if(setting instanceof S.EnumIntSetting) + else if(setting.type === "enum") return enumIntSettingComponent - else if(setting instanceof S.NumberSetting) + else if(setting.type === "number") return numberSettingComponent - else if(setting instanceof S.ExpressionSetting) + else if(setting.type === "expression") return expressionSettingComponent - else if(setting instanceof S.StringSetting) + else if(setting.type === "string") return stringSettingComponent else - console.log('Unknown setting type!', modelData.constructor) + console.log('Unknown setting type!', setting.constructor.name, setting.constructor) } } } diff --git a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs index 0407ee1..40ac532 100644 --- a/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs +++ b/LogarithmPlotter/qml/eu/ad5001/LogarithmPlotter/js/preferences.mjs @@ -37,4 +37,4 @@ class PreferencesAPI extends Module { /** @type {CanvasAPI} */ Modules.Preferences = Modules.Preferences || new PreferencesAPI() -export const API = Modules.Preferences \ No newline at end of file +export const API = Modules.Preferences diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 259edb1..76922ed 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -149,13 +149,13 @@
    - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-v0.5.0-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-v0.5.0-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/LogarithmPlotter-v0.5.0-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/LogarithmPlotter-v0.5.0-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-0.5.0.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.5.0/logarithmplotter-0.5.0.tar.gz
    @@ -198,13 +198,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-v0.4.0-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-v0.4.0-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/LogarithmPlotter-v0.4.0-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/LogarithmPlotter-v0.4.0-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-0.4.0.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.4.0/logarithmplotter-0.4.0.tar.gz @@ -264,13 +264,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-v0.3.0-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-v0.3.0-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/LogarithmPlotter-v0.3.0-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/LogarithmPlotter-v0.3.0-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-0.3.0.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.3.0/logarithmplotter-0.3.0.tar.gz @@ -317,13 +317,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-v0.2.0-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-v0.2.0-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/LogarithmPlotter-v0.2.0-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/LogarithmPlotter-v0.2.0-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-0.2.0.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.2.0/logarithmplotter-0.2.0.tar.gz @@ -362,13 +362,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-v0.1.8-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-v0.1.8-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/LogarithmPlotter-v0.1.8-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/LogarithmPlotter-v0.1.8-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-0.1.8.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.8/logarithmplotter-0.1.8.tar.gz @@ -418,13 +418,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-v0.1.7-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-v0.1.7-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/LogarithmPlotter-v0.1.7-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/LogarithmPlotter-v0.1.7-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-0.1.7.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.7/logarithmplotter-0.1.7.tar.gz @@ -459,13 +459,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/logarithmplotter-v0.1.6-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/logarithmplotter-v0.1.6-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.6/LogarithmPlotter-v0.1.6.tar.gz @@ -489,13 +489,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/logarithmplotter-v0.1.5-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/logarithmplotter-v0.1.5-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.5/LogarithmPlotter-v0.1.5.tar.gz @@ -520,13 +520,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/logarithmplotter-v0.1.4-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/logarithmplotter-v0.1.4-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.4/LogarithmPlotter-v0.1.4.tar.gz @@ -541,13 +541,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/logarithmplotter-v0.1.3-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/logarithmplotter-v0.1.3-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.3/LogarithmPlotter-v0.1.3.tar.gz @@ -565,13 +565,13 @@ - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/logarithmplotter-v0.1.2-setup.exe + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/logarithmplotter-v0.1.2-setup.exe - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2-setup.dmg + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2-setup.dmg - https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2.tar.gz + https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v0.1.2/LogarithmPlotter-v0.1.2.tar.gz diff --git a/linux/generate-appstream-changelog.sh b/linux/generate-appstream-changelog.sh index 331239f..c72e0d4 100644 --- a/linux/generate-appstream-changelog.sh +++ b/linux/generate-appstream-changelog.sh @@ -11,13 +11,13 @@ BEGIN { print " " print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" print " " print " " print " " @@ -58,13 +58,13 @@ BEGIN { print " " print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" print " " print " " print " " @@ -74,13 +74,13 @@ END { print " " print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-v"version"-setup.exe" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/LogarithmPlotter-v"version"-setup.dmg" print " " print " " - print " https://artifacts.accountfree.org/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" + print " https://artifacts.ad5001.eu/repository/apps.ad5001.eu-apps/logarithmplotter/v"version"/logarithmplotter-"version".tar.gz" print " " print " " print " " From 88797d00be9bd30f83a8d07be2ef49f6c2e911f1 Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 19:34:35 +0200 Subject: [PATCH 197/436] Adding new translations for v0.6.0 + adding Spanish credits --- LogarithmPlotter/i18n/lp_de.ts | 172 ++++--- LogarithmPlotter/i18n/lp_en.ts | 165 +++---- LogarithmPlotter/i18n/lp_es.ts | 641 +++++++++++++-------------- LogarithmPlotter/i18n/lp_fr.ts | 172 ++++--- LogarithmPlotter/i18n/lp_hu.ts | 169 ++++--- LogarithmPlotter/i18n/lp_nb_NO.ts | 220 ++++----- LogarithmPlotter/i18n/lp_template.ts | 252 ++++------- README.md | 3 +- 8 files changed, 806 insertions(+), 988 deletions(-) diff --git a/LogarithmPlotter/i18n/lp_de.ts b/LogarithmPlotter/i18n/lp_de.ts index 393e01f..8fa02e1 100644 --- a/LogarithmPlotter/i18n/lp_de.ts +++ b/LogarithmPlotter/i18n/lp_de.ts @@ -33,147 +33,143 @@ AppMenuBar - + &File &Datei - + &Load... &Laden… - + &Save &Speichern - + Save &As... Speichern &Unter… - + &Quit &Ausfahrt - + &Edit &Bearbeiten - + &Undo &Lösen - + &Redo &Wiederherstellen - + &Copy plot Grafik &Kopieren - + + &Preferences + + + + &Create &Erstellen - &Settings &Einstellungen - Check for updates on startup Beim Starten auf Updates prüfen - Reset redo stack automaticly Wiederherstellen-Stapel automatisch zurücksetzen - Enable LaTeX rendering LaTeX-Rendering aktivieren - Expression editor Ausdruckseditor - Automatically close parenthesises and brackets Klammern automatisch schließen - Enable syntax highlighting Syntaxhervorhebung einschalten - Enable autocompletion Automatische Vervollständigung einschalten - Color Scheme Syntaktische Färbung - + &Help &Hilfe - + &Source code &Quellcode - + &Report a bug Fehler &Melden - + &User manual &Benutzerhandbuch - + &Changelog &Changelog - + &Help translating! &Hilfe beim Übersetzen! - + &Thanks &Danksagungen - + &About &Übrigens - + Save unsaved changes? Änderungen speichern? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Diese Grafik enthält ungespeicherte Änderungen. Dadurch gehen alle ungespeicherten Daten verloren. Fortfahren? @@ -189,7 +185,6 @@ BoolSetting - Check for updates on startup Beim Starten auf Updates prüfen @@ -298,32 +293,32 @@ ExpressionEditor - + Object Properties Objekteigenschaften - + Variables Variablen - + Constants Konstanten - + Functions Funktion - + Executable Objects Funktionsobjekte - + Objects Objekte @@ -344,69 +339,66 @@ GreetScreen - + Welcome to LogarithmPlotter Willkommen bei LogarithmPlotter - + Version %1 Version %1 - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Nehmen Sie sich ein paar Sekunden Zeit, um LogarithmPlotter zu konfigurieren. Diese Einstellungen können jederzeit über das Menü "Einstellungen" geändert werden. - Check for updates on startup (requires online connectivity) Beim Start nach Updates suchen (Online-Verbindung erforderlich) - Reset redo stack when a new action is added to history Redo-Stapel zurücksetzen, wenn eine neue Aktion zur Historie hinzugefügt wird - Enable LaTeX rendering LaTeX-Rendering aktivieren - Automatically close parenthesises and brackets in expressions Automatisches Schließen von Klammern in Ausdrücken - Enable syntax highlighting for expressions Syntaxhervorhebung für Ausdrücke einschalten - Enable autocompletion interface in expression editor Schnittstelle zur automatischen Vervollständigung im Ausdruckseditor aktivieren - Color scheme: Syntaktische Färbung Thema: - + User manual Benutzerhandbuch - + Changelog Changelog - + + Preferences + + + + Close Schließen @@ -610,6 +602,14 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" (keine Auswahl ausgewählt) + + Preferences + + + Close + Schließen + + Settings @@ -618,97 +618,96 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Zoom auf X - + Y Zoom Zoom auf Y - + Min X Minimum X - + Max Y Maximum Y - + Max X Maximum X - + Min Y Minimum Y - + X Axis Step X-Achsen-Schritt - + Y Axis Step Y-Achsen-Schritt - + Line width Linienbreite - + Text size (px) Textgröße (px) - + X Label Etikett der X-Achse - + Y Label Etikett der Y-Achse - + X Log scale Logarithmische Skala in X - + Show X graduation X-Teilung anzeigen - + Show Y graduation Y-Teilung anzeigen - + Copy to clipboard Kopieren in die Zwischenablage - + Save plot Grafik speichern - + Save plot as Grafik speichern unter - + Load plot Grafik laden - Close Schließen @@ -853,10 +852,10 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" control - - + + - + %1: %1: @@ -1023,27 +1022,27 @@ Diese Einstellungen können jederzeit über das Menü "Einstellungen" Ende des Ausdrucks - + No object found with names %1. Kein Objekt mit Namen %1 gefunden. - + No object found with name %1. Kein Objekt mit dem Namen %1 gefunden. - + Object cannot be dependent on itself. Ein Objekt kann nicht von sich selbst abhängen. - + Circular dependency detected. Object %1 depends on %2. Zirkuläre Abhängigkeit entdeckt. Objekt %1 hängt von %2 ab. - + Circular dependency detected. Objects %1 depend on %2. Zirkuläre Abhängigkeit entdeckt. Objekte %1 hängen von %2 ab. @@ -1074,12 +1073,12 @@ Die letzte Änderung wurde rückgängig gemacht. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Analysefehler - + Error while parsing expression for property %1: %2 @@ -1251,7 +1250,7 @@ Andernfalls können Sie eine LaTeX-Distribution wie TeX Live unter https://tug.o DVIPNG wurde nicht gefunden. Stellen Sie sicher, dass Sie es aus Ihrer LaTeX-Distribution einbinden. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1264,7 +1263,12 @@ Der Prozess '{}' wurde mit einem Rückgabecode ungleich Null beendet { Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melden Sie einen Fehler, falls dies der Fall ist. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1543,14 +1547,6 @@ Bitte vergewissern Sie sich, dass Ihre LaTeX-Installation korrekt ist, und melde Folgen - - settingCategory - - - general - - - sommegainsbode diff --git a/LogarithmPlotter/i18n/lp_en.ts b/LogarithmPlotter/i18n/lp_en.ts index dbc3714..2f4ea77 100644 --- a/LogarithmPlotter/i18n/lp_en.ts +++ b/LogarithmPlotter/i18n/lp_en.ts @@ -33,147 +33,143 @@ AppMenuBar - + &File &File - + &Load... &Open… - + &Save &Save - + Save &As... Save &As… - + &Quit &Quit - + &Edit &Edit - + &Undo &Undo - + &Redo &Redo - + &Copy plot &Copy plot - + + &Preferences + + + + &Create &Create - &Settings &Settings - Check for updates on startup Check for updates on startup - Reset redo stack automaticly Reset redo stack automatically - Enable LaTeX rendering Enable LaTeX rendering - Expression editor Expression editor - Automatically close parenthesises and brackets Automatically close parentheses and brackets - Enable syntax highlighting Enable syntax highlighting - Enable autocompletion Enable autocompletion - Color Scheme Color Scheme - + &Help &Help - + &Source code &Source code - + &Report a bug &Report a bug - + &User manual &User manual - + &Changelog &Changelog - + &Help translating! &Help translating! - + &Thanks &Thanks - + &About &About - + Save unsaved changes? Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -189,7 +185,6 @@ BoolSetting - Check for updates on startup Check for updates on startup @@ -298,32 +293,32 @@ ExpressionEditor - + Object Properties Object Properties - + Variables Variables - + Constants Constants - + Functions Functions - + Executable Objects Function Objects - + Objects Objects @@ -344,69 +339,66 @@ GreetScreen - + Welcome to LogarithmPlotter Welcome to LogarithmPlotter - + Version %1 Version %1 - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. - Check for updates on startup (requires online connectivity) Check for updates on startup (requires online connectivity) - Reset redo stack when a new action is added to history Reset redo stack when a new action is added to history - Enable LaTeX rendering Enable LaTeX rendering - Automatically close parenthesises and brackets in expressions Automatically close parentheses and brackets in expressions - Enable syntax highlighting for expressions Enable syntax highlighting for expressions - Enable autocompletion interface in expression editor Enable autocompletion interface in expression editor - Color scheme: Color scheme: - + User manual User manual - + Changelog Changelog - + + Preferences + + + + Close Close @@ -610,6 +602,14 @@ These settings can be changed at any time from the "Settings" menu.(no pick selected) + + Preferences + + + Close + Close + + Settings @@ -618,97 +618,96 @@ These settings can be changed at any time from the "Settings" menu.X Zoom - + Y Zoom Y Zoom - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step X Axis Step - + Y Axis Step Y Axis Step - + Line width Line width - + Text size (px) Text size (px) - + X Label X Label - + Y Label Y Label - + X Log scale X Log scale - + Show X graduation Show X graduation - + Show Y graduation Show Y graduation - + Copy to clipboard Copy to clipboard - + Save plot Save plot - + Save plot as Save plot as - + Load plot Open plot - Close Close @@ -853,10 +852,10 @@ These settings can be changed at any time from the "Settings" menu.control - - + + - + %1: %1: @@ -1023,27 +1022,27 @@ These settings can be changed at any time from the "Settings" menu.End of expression - + No object found with names %1. No object found with names %1. - + No object found with name %1. No object found with name %1. - + Object cannot be dependent on itself. Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. Circular dependency detected. Objects %1 depend on %2. @@ -1074,12 +1073,12 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1251,7 +1250,7 @@ Otherwise, you can download a LaTeX distribution like TeX Live at https://tug.or DVIPNG was not found. Make sure you include it from your LaTeX distribution. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1264,7 +1263,12 @@ Process '{}' ended with a non-zero return code {}: Please make sure your LaTeX installation is correct and report a bug if so. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1546,7 +1550,6 @@ Please make sure your LaTeX installation is correct and report a bug if so. settingCategory - general General diff --git a/LogarithmPlotter/i18n/lp_es.ts b/LogarithmPlotter/i18n/lp_es.ts index 46b9a2e..bb33fbe 100644 --- a/LogarithmPlotter/i18n/lp_es.ts +++ b/LogarithmPlotter/i18n/lp_es.ts @@ -33,147 +33,139 @@ AppMenuBar - + &File &Archivo - + &Load... &Abrir… - + &Save &Guardar - + Save &As... Guardar &como… - + &Quit &Salida - + &Edit &Editar - + &Undo &Cancelar - + &Redo &Reiniciar - + &Copy plot &Copiar el gráfico - + + &Preferences + + + + &Create &Crear - &Settings &Ajustes - Check for updates on startup Comprobación de las actualizaciones al arrancar - Reset redo stack automaticly Restablecer la pila de rehacer automáticamente - Enable LaTeX rendering Activar el renderizado de LaTeX - - Expression editor - - - - Automatically close parenthesises and brackets Cerrar automáticamente paréntesis y corchetes - Enable syntax highlighting Activar el resaltado sintáctico - Enable autocompletion Activar autocompletar - Color Scheme Esquema de colores - + &Help &Ayuda - + &Source code &Código fuente - + &Report a bug &Informar de un error - + &User manual &Manual del usuario - + &Changelog &Registro de cambios - + &Help translating! &¡Ayuda a la traducción! - + &Thanks &Agradecimientos - + &About &Acerca de - + Save unsaved changes? ¿Guardar los cambios no guardados? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Este gráfico contiene cambios sin guardar. Al hacer esto, se perderán todos los datos no guardados. ¿Continuar? @@ -189,7 +181,6 @@ BoolSetting - Check for updates on startup Comprobación de las actualizaciones al arrancar @@ -264,35 +255,66 @@ nombre + valor + + EditorDialog + + Label content + Contenido de la etiqueta + + + null + nulo + + + name + nombre + + + name + value + nombre + valor + + + + Create new %1 + + Crear nuevo %1 + + + Edit properties of %1 %2 + Editar propiedades de %1 %2 + + + Name + Nombre + + ExpressionEditor - + Object Properties Propiedades de los objetos - + Variables - + Constants Constantes - + Functions Funciones - + Executable Objects - + Objects @@ -313,68 +335,36 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - - Take a few seconds to configure LogarithmPlotter. -These settings can be changed at any time from the "Settings" menu. - - - - - Check for updates on startup (requires online connectivity) - - - - - Reset redo stack when a new action is added to history - - - - Enable LaTeX rendering Activar el renderizado de LaTeX - - Automatically close parenthesises and brackets in expressions - - - - - Enable syntax highlighting for expressions - - - - - Enable autocompletion interface in expression editor - - - - - Color scheme: - - - - + User manual - + Changelog - + + Preferences + + + + Close @@ -578,6 +568,14 @@ These settings can be changed at any time from the "Settings" menu.Ajustar a la cuadrícula + + Preferences + + + Close + Cerrar + + Settings @@ -586,100 +584,95 @@ These settings can be changed at any time from the "Settings" menu. - + Y Zoom - + Min X - + Max Y - + Max X - + Min Y - + X Axis Step - + Y Axis Step - + Line width - + Text size (px) - + X Label - + Y Label - + X Log scale - + Show X graduation - + Show Y graduation - + Copy to clipboard - + Save plot - + Save plot as - + Load plot - - - Close - - ThanksTo @@ -787,18 +780,73 @@ These settings can be changed at any time from the "Settings" menu. + + color + + %1 %2's color changed from %3 to %4. + El color de %1 %2 cambió de %3 a %4. + + + + comment + + Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} + Ej: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} + + + The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) + Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) + + + Note: Specify the probability for each value. + Nota: Especifique la probabilidad para cada valor. + + + Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... + Nota: Utilice %1[n] para referirse a %1ₙ, %1[n+1] para %1ₙ₊₁… + + + If you have latex enabled, you can use use latex markup in between $$ to create equations. + Si tiene habilitado el latex, puede utilizar el marcado de latex entre $$ para crear ecuaciones. + + control - - + + - + %1: + + create + + New %1 %2 created. + Se ha creado un nuevo %1 %2. + + + + delete + + %1 %2 deleted. + %1 %2 borrados. + + + + editproperty + + %1 of %2 %3 changed from "%4" to "%5". + %1 de %2 %3 cambió de "%4" a "%5". + + + %1 of %2 changed from %3 to %4. + %1 de %2 ha cambiado de %3 a %4. + + error @@ -928,27 +976,27 @@ These settings can be changed at any time from the "Settings" menu. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -981,12 +1029,12 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -999,6 +1047,36 @@ Evaluated expression: %3 + + function + + Function + Función + + + Functions + Funciones + + + + gainbode + + high-pass + Filtro paso alto + + + low-pass + Filtro paso bajo + + + Bode Magnitude + Magnitud de Bode + + + Bode Magnitudes + Magnitudes de Bode + + general @@ -1014,6 +1092,60 @@ Evaluated expression: %3 Activar el renderizado de LaTeX + + historylib + + %1 %2 deleted. + %1 %2 borrados. + + + %1 %2 shown. + Se muestra %1 %2. + + + %1 %2 hidden. + Se oculta %1 %2. + + + New %1 %2 created. + Se ha creado un nuevo %1 %2. + + + Name of %1 %2 changed to %3. + El nombre de %1 %2 se ha cambiado por %3. + + + %1 of %2 %3 changed from "%4" to "%5". + %1 de %2 %3 cambió de "%4" a "%5". + + + + io + + History + Historial + + + Copied plot screenshot to clipboard! + ¡Captura de pantalla del gráfico copiada al portapapeles! + + + &Update + &Actualizar + + + &Update LogarithmPlotter + &Actualizar LogarithmPlotter + + + Settings + Ajustes + + + Objects + Objetos + + latex @@ -1029,7 +1161,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1038,7 +1170,12 @@ Please make sure your latex installation is correct and report a bug if so. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1047,11 +1184,53 @@ Please make sure your latex installation is correct and report a bug if so. - settingCategory + name - - general - + %1 %2 renamed to %3. + %1 %2 ha sido renombrado a %3. + + + + parameters + + below + ↓ Abajo + + + left + ← Izquierda + + + above-left + ↖ Arriba a la izquierda + + + below-left + ↙ Abajo a la izquierda + + + below-right + ↘ Arriba a la derecha + + + center + >|< Centro + + + top + ↑ Arriba + + + above + ↑ Arriba + + + right + → Derecha + + + above-right + ↗ Arriba a la derecha @@ -1115,224 +1294,4 @@ Please make sure your latex installation is correct and report a bug if so. - - io - - History - Historial - - - Copied plot screenshot to clipboard! - ¡Captura de pantalla del gráfico copiada al portapapeles! - - - &Update - &Actualizar - - - &Update LogarithmPlotter - &Actualizar LogarithmPlotter - - - Settings - Ajustes - - - Objects - Objetos - - - - color - - %1 %2's color changed from %3 to %4. - El color de %1 %2 cambió de %3 a %4. - - - - create - - New %1 %2 created. - Se ha creado un nuevo %1 %2. - - - - editproperty - - %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 cambió de "%4" a "%5". - - - %1 of %2 changed from %3 to %4. - %1 de %2 ha cambiado de %3 a %4. - - - - function - - Function - Función - - - Functions - Funciones - - - - gainbode - - high-pass - Filtro paso alto - - - low-pass - Filtro paso bajo - - - Bode Magnitude - Magnitud de Bode - - - Bode Magnitudes - Magnitudes de Bode - - - - historylib - - %1 %2 deleted. - %1 %2 borrados. - - - %1 %2 shown. - Se muestra %1 %2. - - - %1 %2 hidden. - Se oculta %1 %2. - - - New %1 %2 created. - Se ha creado un nuevo %1 %2. - - - Name of %1 %2 changed to %3. - El nombre de %1 %2 se ha cambiado por %3. - - - %1 of %2 %3 changed from "%4" to "%5". - %1 de %2 %3 cambió de "%4" a "%5". - - - - parameters - - below - ↓ Abajo - - - left - ← Izquierda - - - above-left - ↖ Arriba a la izquierda - - - below-left - ↙ Abajo a la izquierda - - - below-right - ↘ Arriba a la derecha - - - center - >|< Centro - - - top - ↑ Arriba - - - above - ↑ Arriba - - - right - → Derecha - - - above-right - ↗ Arriba a la derecha - - - - EditorDialog - - Label content - Contenido de la etiqueta - - - null - nulo - - - name - nombre - - - name + value - nombre + valor - - - + Create new %1 - + Crear nuevo %1 - - - Edit properties of %1 %2 - Editar propiedades de %1 %2 - - - Name - Nombre - - - - comment - - Ex: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ⁻*), ]0;1[, {3;4;5} - Ej: R+* (ℝ⁺*), N (ℕ), Z-* (ℤ-*), ]0;1[, {3;4;5} - - - The following parameters are used when the definition domain is a non-continuous set. (Ex: ℕ, ℤ, sets like {0;3}...) - Los siguientes parámetros se utilizan cuando el dominio es un conjunto no continuo. (Ej: ℕ, ℤ, conjuntos como {0;3}...) - - - Note: Specify the probability for each value. - Nota: Especifique la probabilidad para cada valor. - - - Note: Use %1[n] to refer to %1ₙ, %1[n+1] for %1ₙ₊₁... - Nota: Utilice %1[n] para referirse a %1ₙ, %1[n+1] para %1ₙ₊₁… - - - If you have latex enabled, you can use use latex markup in between $$ to create equations. - Si tiene habilitado el latex, puede utilizar el marcado de latex entre $$ para crear ecuaciones. - - - - delete - - %1 %2 deleted. - %1 %2 borrados. - - - - name - - %1 %2 renamed to %3. - %1 %2 ha sido renombrado a %3. - - diff --git a/LogarithmPlotter/i18n/lp_fr.ts b/LogarithmPlotter/i18n/lp_fr.ts index 3dd5482..aa78b8f 100644 --- a/LogarithmPlotter/i18n/lp_fr.ts +++ b/LogarithmPlotter/i18n/lp_fr.ts @@ -33,148 +33,144 @@ AppMenuBar - + &File &Fichier - + &Load... &Ouvrir… - + &Save &Sauvegarder - + Save &As... Sauvegarde &Sous… - + &Quit &Quitter - + &Edit &Édition - + &Undo &Annuler - + &Redo &Rétablir - + &Copy plot &Copier le graphe - + + &Preferences + + + + &Create &Créer - &Settings &Paramètres - Check for updates on startup Vérifier la présence de mise à jour au démarrage - Reset redo stack automaticly Légèrement long, et pas forcément très compréhensible. Réinitialiser la pile d'action "Rétablir" automatiquement - Enable LaTeX rendering Activer le rendu LaTeX - Expression editor Éditeur de formule - Automatically close parenthesises and brackets Fermer automatiquement les parenthèses et les crochets - Enable syntax highlighting Activer la coloration syntaxique - Enable autocompletion Activer l'autocomplétion - Color Scheme Coloration Syntaxique - + &Help &Aide - + &Source code &Code source - + &Report a bug &Rapport de bug - + &User manual Manuel d'&utilisation - + &Changelog &Historique des modifications - + &Help translating! &Aider à la traduction ! - + &Thanks &Remerciements - + &About &À propos - + Save unsaved changes? Sauvegarder les modifications ? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ce graphe contient des modifications non sauvegardées. En faisant cela, toutes les données non sauvegardées seront perdues. Continuer ? @@ -190,7 +186,6 @@ BoolSetting - Check for updates on startup Vérifier la présence de mise à jour au démarrage @@ -300,32 +295,32 @@ ExpressionEditor - + Object Properties Propriétés de l'objet - + Variables Variables - + Constants Constantes - + Functions Fonctions - + Executable Objects Objets fonction - + Objects Objets @@ -346,59 +341,58 @@ GreetScreen - + Welcome to LogarithmPlotter Bienvenue sur LogarithmPlotter - + Version %1 Version %1 - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Prenez quelques secondes pour configurer LogarithmPlotter. Ces paramètres peuvent être modifiés à tout moment à partir du menu "Paramètres". - Enable LaTeX rendering Activer le rendu LaTeX - Automatically close parenthesises and brackets in expressions Fermer automatiquement les parenthèses et les crochets dans les formules - Enable syntax highlighting for expressions Activer la coloration syntaxique des formules - Enable autocompletion interface in expression editor Activer l'interface d'autocomplétion dans l'éditeur de formules - Color scheme: Thème de coloration syntaxique : - + User manual Manuel d'utilisation - + Changelog Historique des modifications - + + Preferences + + + + Close Fermer @@ -409,12 +403,10 @@ These settings can always be changed at any time from the "Settings" m These settings can always be changed at any time from the "Settings" menu. - Check for updates on startup (requires online connectivity) Vérifier les mises à jour au démarrage (nécessite d'être connecté à internet) - Reset redo stack when a new action is added to history Réinitialiser la pile d'action "Rétablir" lorsqu'une nouvelle action est ajoutée à l'historique @@ -618,6 +610,14 @@ These settings can always be changed at any time from the "Settings" m (aucun axe sélectionné) + + Preferences + + + Close + Fermer + + Settings @@ -626,97 +626,96 @@ These settings can always be changed at any time from the "Settings" m Zoom en X - + Y Zoom Zoom en Y - + Min X Min X - + Max Y Max Y - + Max X Max X - + Min Y Min Y - + X Axis Step Pas de l'axe X - + Y Axis Step Pas de l'axe Y - + Line width Taille des lignes - + Text size (px) Taille du texte (px) - + X Label Label de l'axe X - + Y Label Label de l'axe Y - + X Log scale Échelle logarithmique en X - + Show X graduation Montrer la graduation de l'axe X - + Show Y graduation Montrer la graduation de l'axe Y - + Copy to clipboard Copier vers le presse-papiers - + Save plot Sauvegarder le graphe - + Save plot as Sauvegarder le graphe sous - + Load plot Ouvrir un graphe - Close Fermer @@ -862,10 +861,10 @@ These settings can always be changed at any time from the "Settings" m control - - + + - + %1: %1 : @@ -1032,27 +1031,27 @@ These settings can always be changed at any time from the "Settings" m Fin de la formule - + No object found with names %1. Aucun objet trouvé ayant pour noms %1. - + No object found with name %1. Aucun objet avec le nom %1 n'a été trouvé. - + Object cannot be dependent on itself. Un objet ne peut pas dépendre de lui-même. - + Circular dependency detected. Object %1 depends on %2. Dépendance circulaire détectée. L'objet %1 dépend de %2. - + Circular dependency detected. Objects %1 depend on %2. Dépendance circulaire détectée. Les objets %1 dépendent de %2. @@ -1083,12 +1082,12 @@ La dernière modification a été annulée. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Erreur de syntaxe - + Error while parsing expression for property %1: %2 @@ -1260,7 +1259,7 @@ Sinon, vous pouvez télécharger une distribution LaTeX comme TeX Live à l&apos DVIPNG n'a pas été trouvé. Assurez-vous de l'inclure dans votre distribution LaTeX. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1273,7 +1272,12 @@ Le processus '{}' s'est terminé par un code de retour non nul {} Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c'est le cas. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1552,14 +1556,6 @@ Vérifiez que votre installation de LaTeX est correcte et signalez un bogue si c Suites - - settingCategory - - - general - - - sommegainsbode diff --git a/LogarithmPlotter/i18n/lp_hu.ts b/LogarithmPlotter/i18n/lp_hu.ts index a7d3804..0252785 100644 --- a/LogarithmPlotter/i18n/lp_hu.ts +++ b/LogarithmPlotter/i18n/lp_hu.ts @@ -33,147 +33,143 @@ AppMenuBar - + &File &Fájl - + &Load... &Betöltés… - + &Save &Mentés - + Save &As... Me&ntés másként… - + &Quit &Kilépés - + &Edit S&zerkesztés - + &Undo &Visszavonás - + &Redo &Ismétlés - + &Copy plot Ábra má&solása - + + &Preferences + + + + &Create &Létrehozás - &Settings &Beállítások - Check for updates on startup Frissítések keresése indításkor - Reset redo stack automaticly Ismétlési verem önműködő visszaállítása - Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - Expression editor Kifejezésszerkesztő - Automatically close parenthesises and brackets Zárójelek automatikus bezárása - Enable syntax highlighting Mondattani kiemelés engedélyezése - Enable autocompletion Automatikus befejezés engedélyezése - Color Scheme Színséma - + &Help &Súgó - + &Source code &Forráskód - + &Report a bug &Hiba bejelentése - + &User manual &Használati utasítás - + &Changelog &Változásnapló - + &Help translating! &Segítség a fordításban! - + &Thanks &Köszönjük - + &About &Névjegy - + Save unsaved changes? Menti a változtatásokat? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? Ez az ábra nem mentett változtatásokat tartalmaz. Ezzel az összes nem mentett adat elveszik. Folytatja? @@ -189,7 +185,6 @@ BoolSetting - Check for updates on startup Frissítések keresése indításkor @@ -298,32 +293,32 @@ ExpressionEditor - + Object Properties Objektumtulajdonságok - + Variables Változók - + Constants Állandók - + Functions Függvények - + Executable Objects Függvényobjektumok - + Objects Objektumok @@ -344,69 +339,66 @@ GreetScreen - + Welcome to LogarithmPlotter Isten hozott a LogarithmPlotter! - + Version %1 %1 verzió - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Szánjon néhány másodpercet a LogarithmPlotter beállításához. Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. - Check for updates on startup (requires online connectivity) Frissítések keresése indításkor (online kapcsolat szükséges) - Reset redo stack when a new action is added to history Ismétlési verem alaphelyzet visszaállítása, ha új műveletet adnak az előzményekhez - Enable LaTeX rendering LaTeX-megjelenítés engedélyezése - Automatically close parenthesises and brackets in expressions Zárójelek automatikus bezárása a kifejezésekben - Enable syntax highlighting for expressions Mondattani kiemelés engedélyezése a kifejezésekhez - Enable autocompletion interface in expression editor Automatikus befejezési felület engedélyezése a kifejezésszerkesztőben - Color scheme: Színséma: - + User manual Használati utasítás - + Changelog Változásnapló - + + Preferences + + + + Close Kész @@ -610,6 +602,14 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. (nincs kijelölés kiválasztva) + + Preferences + + + Close + + + Settings @@ -618,97 +618,96 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. X-nagyítás - + Y Zoom Y-nagyítás - + Min X Legkisebb X - + Max Y Legnagyobb Y - + Max X Legnagyobb X - + Min Y Legkisebb Y - + X Axis Step X tengely lépésköze - + Y Axis Step Y tengely lépésköze - + Line width Vonalvastagság - + Text size (px) Szövegméret (képpont) - + X Label X címke - + Y Label Y címke - + X Log scale X tengely logaritmikus skálával - + Show X graduation X érettségi megjelenítése - + Show Y graduation Y érettségi megjelenítése - + Copy to clipboard Másolás a vágólapra - + Save plot Ábra mentése - + Save plot as Ábra mentése másként - + Load plot Ábra betöltése - Close Kész @@ -853,10 +852,10 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. control - - + + - + %1: %1: @@ -1023,27 +1022,27 @@ Ezek a beállítások bármikor módosíthatók a „Beállítások” menüben. Kifejezés vége - + No object found with names %1. A(z) %1 nevű objektum nem található. - + No object found with name %1. A(z) %1 nevű objektum nem található. - + Object cannot be dependent on itself. Az objektum nem függhet önmagától. - + Circular dependency detected. Object %1 depends on %2. Körkörös függőség észlelve. A(z) %1-objektum a(z) %2-objektumtól függ. - + Circular dependency detected. Objects %1 depend on %2. Körkörös függőség észlelve. A(z) %1-objektumok a(z) %2-objektumtól függenek. @@ -1074,12 +1073,12 @@ Az utolsó módosítás visszavonása. expression - + LogarithmPlotter - Parsing error LogarithmPlotter - Elemzési hiba - + Error while parsing expression for property %1: %2 @@ -1251,7 +1250,7 @@ Egyébként letölthet egy LaTeX disztribúciót, például a TeX Live-t a https DVIPNG nem található. Ügyeljen arra, hogy a LaTeX disztribúciójából tartalmazza. - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1264,7 +1263,12 @@ A(z) „{}” folyamat nullától eltérő visszatérési kóddal ({}) végződ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelentse a hibát. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1545,11 +1549,6 @@ Kérjük, ellenőrizze, hogy a LaTeX telepítése helyes-e, és ha igen, jelents settingCategory - - - general - - editor Kifejezésszerkesztő diff --git a/LogarithmPlotter/i18n/lp_nb_NO.ts b/LogarithmPlotter/i18n/lp_nb_NO.ts index 314a690..99b3698 100644 --- a/LogarithmPlotter/i18n/lp_nb_NO.ts +++ b/LogarithmPlotter/i18n/lp_nb_NO.ts @@ -33,147 +33,119 @@ AppMenuBar - + &File &Fil - + &Load... &Last inn … - + &Save &Lagre - + Save &As... Lagre &som … - + &Quit &Avslutt - + &Edit &Rediger - + &Undo &Angre - + &Redo &Gjenta - + &Copy plot &Kopier plott - + + &Preferences + + + + &Create &Opprett - &Settings &Innstillinger - Check for updates on startup Se etter nye versjoner ved programstart - Reset redo stack automaticly Tilbakestill angrehistorikk automatisk - - Enable LaTeX rendering - - - - - Expression editor - - - - - Automatically close parenthesises and brackets - - - - - Enable syntax highlighting - - - - - Enable autocompletion - - - - - Color Scheme - - - - + &Help &Hjelp - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About &Om - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -189,7 +161,6 @@ BoolSetting - Check for updates on startup Se etter nye versjoner ved programstart @@ -298,32 +269,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions Funksjoner - + Executable Objects - + Objects Objekter @@ -344,69 +315,46 @@ GreetScreen - + Welcome to LogarithmPlotter Velkommen til LogarithmPlotter - + Version %1 Versjon %1 - Take a few seconds to configure LogarithmPlotter. These settings can be changed at any time from the "Settings" menu. Sett opp LogarithmPlotter. Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - Check for updates on startup (requires online connectivity) Se etter nye versjoner ved programstart. (Krever tilkobling til Internett.) - Reset redo stack when a new action is added to history Tilbakesitll angrehistorikk når en ny handling legges til - - Enable LaTeX rendering - - - - - Automatically close parenthesises and brackets in expressions - - - - - Enable syntax highlighting for expressions - - - - - Enable autocompletion interface in expression editor - - - - - Color scheme: - - - - + User manual - + Changelog - + + Preferences + + + + Close @@ -610,6 +558,14 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. + + Preferences + + + Close + + + Settings @@ -618,100 +574,95 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.X-forstørrelse - + Y Zoom Y-forstørrelse - + Min X Min. X - + Max Y Maks. Y - + Max X Maks. X - + Min Y Min. Y - + X Axis Step X-aksesteg - + Y Axis Step Y-aksesteg - + Line width Linjebredde - + Text size (px) Tekststørrelse (piksler) - + X Label Navn på X-akse - + Y Label Navn på Y-akse - + X Log scale Logaritmisk skala i x - + Show X graduation Vis X-inndeling - + Show Y graduation Vis Y-inndeling - + Copy to clipboard Kopier til utklippstavle - + Save plot Lagre plott - + Save plot as Lagre plott som - + Load plot Last inn plott - - - Close - - ThanksTo @@ -823,10 +774,10 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen.control - - + + - + %1: @@ -981,27 +932,27 @@ Disse innstillingene kan endres når som helst fra «Innstillinger»-menyen. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -1026,12 +977,12 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -1174,7 +1125,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -1183,7 +1134,12 @@ Please make sure your latex installation is correct and report a bug if so. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -1235,14 +1191,6 @@ Please make sure your latex installation is correct and report a bug if so.Følger - - settingCategory - - - general - - - sommegainsbode diff --git a/LogarithmPlotter/i18n/lp_template.ts b/LogarithmPlotter/i18n/lp_template.ts index 426049e..55e57b6 100644 --- a/LogarithmPlotter/i18n/lp_template.ts +++ b/LogarithmPlotter/i18n/lp_template.ts @@ -33,147 +33,107 @@ AppMenuBar - + &File - + &Load... - + &Save - + Save &As... - + &Quit - + &Edit - + &Undo - + &Redo - + &Copy plot - + + &Preferences + + + + &Create - - &Settings - - - - - Check for updates on startup - - - - - Reset redo stack automaticly - - - - - Enable LaTeX rendering - - - - - Expression editor - - - - - Automatically close parenthesises and brackets - - - - - Enable syntax highlighting - - - - - Enable autocompletion - - - - - Color Scheme - - - - + &Help - + &Source code - + &Report a bug - + &User manual - + &Changelog - + &Help translating! - + &Thanks - + &About - + Save unsaved changes? - + This plot contains unsaved changes. By doing this, all unsaved data will be lost. Continue? @@ -186,14 +146,6 @@ - - BoolSetting - - - Check for updates on startup - - - Changelog @@ -267,32 +219,32 @@ ExpressionEditor - + Object Properties - + Variables - + Constants - + Functions - + Executable Objects - + Objects @@ -313,68 +265,32 @@ GreetScreen - + Welcome to LogarithmPlotter - + Version %1 - - Take a few seconds to configure LogarithmPlotter. -These settings can be changed at any time from the "Settings" menu. - - - - - Check for updates on startup (requires online connectivity) - - - - - Reset redo stack when a new action is added to history - - - - - Enable LaTeX rendering - - - - - Automatically close parenthesises and brackets in expressions - - - - - Enable syntax highlighting for expressions - - - - - Enable autocompletion interface in expression editor - - - - - Color scheme: - - - - + User manual - + Changelog - + + Preferences + + + + Close @@ -530,6 +446,14 @@ These settings can be changed at any time from the "Settings" menu. + + Preferences + + + Close + + + Settings @@ -538,100 +462,95 @@ These settings can be changed at any time from the "Settings" menu. - + Y Zoom - + Min X - + Max Y - + Max X - + Min Y - + X Axis Step - + Y Axis Step - + Line width - + Text size (px) - + X Label - + Y Label - + X Log scale - + Show X graduation - + Show Y graduation - + Copy to clipboard - + Save plot - + Save plot as - + Load plot - - - Close - - ThanksTo @@ -743,10 +662,10 @@ These settings can be changed at any time from the "Settings" menu.control - - + + - + %1: @@ -880,27 +799,27 @@ These settings can be changed at any time from the "Settings" menu. - + No object found with names %1. - + No object found with name %1. - + Object cannot be dependent on itself. - + Circular dependency detected. Object %1 depends on %2. - + Circular dependency detected. Objects %1 depend on %2. @@ -925,12 +844,12 @@ Undoing last change. expression - + LogarithmPlotter - Parsing error - + Error while parsing expression for property %1: %2 @@ -958,7 +877,7 @@ Otherwise, you can download a Latex distribution like TeX Live at https://tug.or - + An exception occured within the creation of the latex formula. Process '{}' ended with a non-zero return code {}: @@ -967,7 +886,12 @@ Please make sure your latex installation is correct and report a bug if so. - + + Your LaTeX installation does not include the '{}' package. Make sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter. + + + + An exception occured within the creation of the latex formula. Process '{}' took too long to finish: {} @@ -975,14 +899,6 @@ Please make sure your latex installation is correct and report a bug if so. - - settingCategory - - - general - - - update diff --git a/README.md b/README.md index 026528f..a60a9a5 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,9 @@ There are several ways to contribute to LogarithmPlotter. along with this program. If not, see . Language files translations located at LogarithmPlotter/i18n are licensed under GNU GPL3.0+ and are copyrighted by their original authors. See LICENSE.md for more details: -- 🇳🇴 Norwegian translation by [Allan Nordhøy](https://github.com/comradekingu) - 🇭🇺 Hungarian translation by [Óvári](https://github.com/ovari) +- 🇳🇴 Norwegian translation by [Allan Nordhøy](https://github.com/comradekingu) +- 🇪🇸 Spanish translation by gallegonovato and [IngrownMink4](https://github.com/IngrownMink4) ### Libraries used From 4b1cf2cd9d1b933e8cb54cd3a9c68f59021ba65c Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Mon, 16 Sep 2024 20:00:56 +0200 Subject: [PATCH 198/436] Improving linux metainfo generation. --- linux/eu.ad5001.LogarithmPlotter.metainfo.xml | 162 ++++++++++-------- linux/generate-appstream-changelog.sh | 2 +- 2 files changed, 89 insertions(+), 75 deletions(-) diff --git a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml index 76922ed..6b5847b 100644 --- a/linux/eu.ad5001.LogarithmPlotter.metainfo.xml +++ b/linux/eu.ad5001.LogarithmPlotter.metainfo.xml @@ -1,77 +1,66 @@ - - + + eu.ad5001.LogarithmPlotter - eu.ad5001.LogarithmPlotter.desktop logarithmplotter.desktop CC0-1.0 GPL-3.0+ LogarithmPlotter - http://apps.ad5001.eu/icons/apps/svg/logarithmplotter.svg + https://apps.ad5001.eu/icons/apps/svg/logarithmplotter.svg Create and edit Bode plots Erstellen und Bearbeiten von Bode-Diagrammen Créez et éditez des diagrammes de Bode Bode-diagramok létrehozása és szerkesztése Opprette og redigere Bode-diagrammer -

    LogarithmPlotter is, as it's name suggests, a plotter made with logarithm scales in mind. With an object system similar to Geogebra's, it allows dynamic creation of both logarithmic-scaled and non logarithmic-scaled plots with very few limitations.

    +

    + LogarithmPlotter est, comme son nom l'indique, un créateur de graphes et diagrammes 2D réalisé avec l'échelle logarithmique en tête. Avec un système d'objets similaire à Geogebra, ce qui lui permet de créer des graphes à échelle logarithmique et non logarithmique avec peu de limitations. +

    +

    + A LogarithmPlotter egy logaritmus-ábrázoló, amely logaritmikus léptékek figyelembevételével készült. A Geogebrához hasonló objektumrendszerrel dinamikus parcellák létrehozását teszi lehetővé, nagyon kevés korlátozással. +

    It's primary use is to quickly create asymptotic Bode plots, but it's extensible nature and ability to switch to non-logarithmic scales allow it to create other things with it, like sequences or statistical repartition functions.

    +

    + Son intérêt principal est de permettre de créer des diagrammes asymptotiques de Bode, mais sa nature extensible et sa capacité à passer à une échelle non-logarithmique lui permet de créer d'autres choses. +

    +

    + Elsődleges felhasználása az aszimptotikus Bode-ábrák gyors létrehozása, de bővíthető jellege és a nem logaritmikus skálákra váltás lehetősége lehetővé teszi, hogy más dolgokat is létrehozzon vele, például sorozatokat vagy statisztikai újraosztási függvényeket. +

    Features:

    +

    Fonctionnalités:

    • Graphical objects (points, fonctions, Bode magnitudes...) management system
    • Complete object edition
    • Advanced history system
    • Diagram looks customisation
    • +
    • Système de gestion des objets graphiques (points, fonctions, gains de Bode...)
    • +
    • Modification complète des objets
    • +
    • Système d'historique avancé
    • +
    • Personnalisation de l'apparence des diagrammes

    LogarithmPlotter is available in:

    +

    LogarithmPlotter est disponible en:

    • 🇬🇧 English
    • 🇫🇷 French
    • 🇩🇪 German
    • 🇭🇺 Hungarian
    • 🇳🇴 Norwergian
    • +
    • 🇪🇸 Spanish
    • +
    • 🇬🇧 Anglais
    • +
    • 🇫🇷 Français
    • +
    • 🇩🇪 Allemand
    • +
    • 🇭🇺 Hongrois
    • +
    • 🇳🇴 Norvégien
    • +
    • 🇪🇸 Espagnol
    -

    Learn more: https://apps.ad5001.eu/logarithmplotter/

    -

    - LogarithmPlotter est, comme son nom l'indique, un créateur de graphes et diagrammes 2D réalisé avec l'échelle logarithmique en tête. Avec un système d'objets similaire à Geogebra, ce qui lui permet de créer des graphes à échelle logarithmique et non logarithmique avec peu de limitations. -

    -

    - Son intérêt principal est de permettre de créer des diagrammes asymptotiques de Bode, mais sa nature extensible et sa capacité à passer à une échelle non-logarithmique lui permet de créer d'autres choses. -

    -

    Fonctionnalités:

    -
      -
    • Système de gestion des objets graphiques (points, fonctions, gains de Bode...)
    • -
    • Modification complète des objets
    • -
    • Système d'historique avancé
    • -
    • Personnalisation de l'apparence des diagrammes
    • -
    -

    LogarithmPlotter est disponible en:

    -
      -
    • 🇬🇧 Anglais
    • -
    • 🇫🇷 Français
    • -
    • 🇩🇪 Allemand
    • -
    • 🇭🇺 Hongrois
    • -
    • 🇳🇴 Norvégien
    • -
    -

    En savoir plus: https://apps.ad5001.eu/fr/logarithmplotter/

    -

    - A LogarithmPlotter egy logaritmus-ábrázoló, amely logaritmikus léptékek figyelembevételével készült. A Geogebrához hasonló objektumrendszerrel dinamikus parcellák létrehozását teszi lehetővé, nagyon kevés korlátozással. -

    -

    - Elsődleges felhasználása az aszimptotikus Bode-ábrák gyors létrehozása, de bővíthető jellege és a nem logaritmikus skálákra váltás lehetősége lehetővé teszi, hogy más dolgokat is létrehozzon vele, például sorozatokat vagy statisztikai újraosztási függvényeket. -

    @@ -84,40 +73,62 @@ https://git.ad5001.eu/Ad5001/LogarithmPlotter/issues/ https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/ https://hosted.weblate.org/engage/logarithmplotter/ + - https://apps.ad5001.eu/img/en/gain.png?v=0.5 - https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/de/gain.png?v=0.5 - https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/fr/gain.png?v=0.5 - https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/hu/gain.png?v=0.5 - https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.5 - https://apps.ad5001.eu/img/no/gain.png?v=0.5 - https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.5 - https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.5 + + https://apps.ad5001.eu/img/en/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/de/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/fr/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/hu/logarithmplotter/gain.png?v=0.5 + https://apps.ad5001.eu/img/no/logarithmplotter/gain.png?v=0.5 + Main view of LogarithmPlotter showing an asymptotic Bode magnitude plot. + Die Hauptansicht des LogarithmPlotters zeigt eine asymptotische Bode-Magnitude-Darstellung. + Vue principale de LogarithmPlotter montrant un tracé asymptotique d'une magnitude de Bode. + A LogarithmPlotter fő nézete, amely egy aszimptotikus Bode-magnitúdó ábrát mutat. + Hovedvisning av LogarithmPlotter som viser et asymptotisk Bode-størrelsesplott. + + + https://apps.ad5001.eu/img/en/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/de/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/fr/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/hu/logarithmplotter/phase.png?v=0.5 + https://apps.ad5001.eu/img/no/logarithmplotter/phase.png?v=0.5 + Main view of LogarithmPlotter showing an asymptotic Bode phase plot. + Hauptansicht des LogarithmPlotters mit einer asymptotischen Bode-Phasendarstellung. + Vue principale de LogarithmPlotter montrant un tracé asymptotique d'une phase de Bode. + A LogarithmPlotter fő nézete, amely egy aszimptotikus Bode-fázis ábrát mutat. + Hovedvisning av LogarithmPlotter som viser et asymptotisk Bode-fasediagram. + + + https://apps.ad5001.eu/img/en/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/de/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/fr/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/hu/logarithmplotter/welcome.png?v=0.5 + https://apps.ad5001.eu/img/no/logarithmplotter/welcome.png?v=0.5 + LogarithmPlotter's welcome page. + LogarithmPlotter's Willkommensseite. + Page d'accueil de LogarithmPlotter. + LogarithmPlotter üdvözlő oldala. + LogarithmPlotters velkomstside. + - + - medium + 768 - xlarge - xsmall + 3840 + 360 - + -

    Changes for v0.5.0:

    +

    Changes for v0.5.0:

    New