This commit is contained in:
parent
b50d56d511
commit
9072e94d14
8 changed files with 66 additions and 28 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -22,15 +22,14 @@ linux/flatpak/.flatpak-builder
|
||||||
**/__pycache__/
|
**/__pycache__/
|
||||||
.ropeproject
|
.ropeproject
|
||||||
.vscode
|
.vscode
|
||||||
|
*.kdev4
|
||||||
|
.kdev4
|
||||||
|
.coverage
|
||||||
build
|
build
|
||||||
docs/html
|
docs/html
|
||||||
.directory
|
.directory
|
||||||
*.kdev4
|
|
||||||
*.lpf
|
*.lpf
|
||||||
*.lgg
|
*.lgg
|
||||||
*.spec
|
*.spec
|
||||||
.kdev4
|
|
||||||
AccountFree.pro
|
|
||||||
AccountFree.pro.user
|
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
|
|
|
@ -21,7 +21,6 @@ from platform import system
|
||||||
from json import load, dumps
|
from json import load, dumps
|
||||||
from PySide6.QtCore import QLocale, QTranslator
|
from PySide6.QtCore import QLocale, QTranslator
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_SETTINGS = {
|
DEFAULT_SETTINGS = {
|
||||||
"check_for_updates": True,
|
"check_for_updates": True,
|
||||||
"reset_redo_stack": True,
|
"reset_redo_stack": True,
|
||||||
|
@ -38,7 +37,7 @@ DEFAULT_SETTINGS = {
|
||||||
"default_graph": {
|
"default_graph": {
|
||||||
"xzoom": 100,
|
"xzoom": 100,
|
||||||
"yzoom": 10,
|
"yzoom": 10,
|
||||||
"xmin": 5/10,
|
"xmin": 5 / 10,
|
||||||
"ymax": 25,
|
"ymax": 25,
|
||||||
"xaxisstep": "4",
|
"xaxisstep": "4",
|
||||||
"yaxisstep": "4",
|
"yaxisstep": "4",
|
||||||
|
@ -55,41 +54,47 @@ DEFAULT_SETTINGS = {
|
||||||
# Create config directory
|
# Create config directory
|
||||||
CONFIG_PATH = {
|
CONFIG_PATH = {
|
||||||
"Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter")
|
"Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter")
|
||||||
if "XDG_CONFIG_HOME" in environ else
|
if "XDG_CONFIG_HOME" in environ else
|
||||||
path.join(path.expanduser("~"), ".config", "LogarithmPlotter"),
|
path.join(path.expanduser("~"), ".config", "LogarithmPlotter"),
|
||||||
"Windows": path.join(path.expandvars('%APPDATA%'), "LogarithmPlotter", "config"),
|
"Windows": path.join(path.expandvars('%APPDATA%'), "LogarithmPlotter", "config"),
|
||||||
"Darwin": path.join(path.expanduser("~"), "Library", "Application Support", "LogarithmPlotter"),
|
"Darwin": path.join(path.expanduser("~"), "Library", "Application Support", "LogarithmPlotter"),
|
||||||
}[system()]
|
}[system()]
|
||||||
|
|
||||||
CONFIG_FILE = path.join(CONFIG_PATH, "config.json")
|
CONFIG_FILE = path.join(CONFIG_PATH, "config.json")
|
||||||
|
|
||||||
initialized = False
|
|
||||||
current_config = DEFAULT_SETTINGS
|
current_config = DEFAULT_SETTINGS
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownNamespaceError(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
"""
|
"""
|
||||||
Initializes the config and loads all possible settings from the file if needs be.
|
Initializes the config and loads all possible settings from the file if needs be.
|
||||||
"""
|
"""
|
||||||
|
global current_config
|
||||||
|
current_config = DEFAULT_SETTINGS
|
||||||
makedirs(CONFIG_PATH, exist_ok=True)
|
makedirs(CONFIG_PATH, exist_ok=True)
|
||||||
|
|
||||||
if path.exists(CONFIG_FILE):
|
if path.exists(CONFIG_FILE):
|
||||||
cfg_data = load(open(CONFIG_FILE, 'r', -1, 'utf8'))
|
cfg_data = load(open(CONFIG_FILE, 'r', -1, 'utf8'))
|
||||||
for setting_name in cfg_data:
|
for setting_name in cfg_data:
|
||||||
if type(cfg_data[setting_name]) == dict:
|
if type(cfg_data[setting_name]) == dict:
|
||||||
for setting_name2 in cfg_data[setting_name]:
|
for setting_name2 in cfg_data[setting_name]:
|
||||||
setSetting(setting_name+"."+setting_name2, cfg_data[setting_name][setting_name2])
|
setSetting(setting_name + "." + setting_name2, cfg_data[setting_name][setting_name2])
|
||||||
else:
|
else:
|
||||||
setSetting(setting_name, cfg_data[setting_name])
|
setSetting(setting_name, cfg_data[setting_name])
|
||||||
|
|
||||||
def save():
|
|
||||||
|
def save(file=CONFIG_FILE):
|
||||||
"""
|
"""
|
||||||
Saves the config to the path.
|
Saves the config to the path.
|
||||||
"""
|
"""
|
||||||
write_file = open(CONFIG_FILE, 'w', -1, 'utf8')
|
write_file = open(file, 'w', -1, 'utf8')
|
||||||
write_file.write(dumps(current_config))
|
write_file.write(dumps(current_config))
|
||||||
write_file.close()
|
write_file.close()
|
||||||
|
|
||||||
|
|
||||||
def getSetting(namespace):
|
def getSetting(namespace):
|
||||||
"""
|
"""
|
||||||
Returns a setting from a namespace.
|
Returns a setting from a namespace.
|
||||||
|
@ -103,9 +108,10 @@ def getSetting(namespace):
|
||||||
setting = setting[name]
|
setting = setting[name]
|
||||||
else:
|
else:
|
||||||
# return namespace # Return original name
|
# return namespace # Return original name
|
||||||
raise ValueError('Setting ' + namespace + ' doesn\'t exist. Debug: ', setting, name)
|
raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}")
|
||||||
return setting
|
return setting
|
||||||
|
|
||||||
|
|
||||||
def setSetting(namespace, data):
|
def setSetting(namespace, data):
|
||||||
"""
|
"""
|
||||||
Sets a setting at a namespace with data.
|
Sets a setting at a namespace with data.
|
||||||
|
@ -119,6 +125,6 @@ def setSetting(namespace, data):
|
||||||
if name in setting:
|
if name in setting:
|
||||||
setting = setting[name]
|
setting = setting[name]
|
||||||
else:
|
else:
|
||||||
raise ValueError('Setting {} doesn\'t exist. Debug: {}, {}'.format(namespace, setting, name))
|
raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}")
|
||||||
else:
|
else:
|
||||||
setting[name] = data
|
setting[name] = data
|
||||||
|
|
|
@ -32,6 +32,9 @@ from LogarithmPlotter import __VERSION__
|
||||||
from LogarithmPlotter.util import config
|
from LogarithmPlotter.util import config
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidFileException(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
class ChangelogFetcher(QRunnable):
|
class ChangelogFetcher(QRunnable):
|
||||||
def __init__(self, helper):
|
def __init__(self, helper):
|
||||||
QRunnable.__init__(self)
|
QRunnable.__init__(self)
|
||||||
|
@ -94,8 +97,8 @@ class Helper(QObject):
|
||||||
pass
|
pass
|
||||||
elif data[:3] == "LPF":
|
elif data[:3] == "LPF":
|
||||||
# More recent version of LogarithmPlotter file, but incompatible with the current format
|
# More recent version of LogarithmPlotter file, but incompatible with the current format
|
||||||
msg = 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__))
|
msg = 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.")
|
||||||
raise Exception(msg)
|
raise InvalidFileException(msg.format(__VERSION__))
|
||||||
else:
|
else:
|
||||||
raise Exception("Invalid LogarithmPlotter file.")
|
raise Exception("Invalid LogarithmPlotter file.")
|
||||||
except Exception as e: # If file can't be loaded
|
except Exception as e: # If file can't be loaded
|
||||||
|
@ -131,7 +134,6 @@ class Helper(QObject):
|
||||||
|
|
||||||
@Slot(str, result=float)
|
@Slot(str, result=float)
|
||||||
def getSettingInt(self, namespace):
|
def getSettingInt(self, namespace):
|
||||||
print('Getting', namespace, config.getSetting(namespace))
|
|
||||||
return config.getSetting(namespace)
|
return config.getSetting(namespace)
|
||||||
|
|
||||||
@Slot(str, result=bool)
|
@Slot(str, result=bool)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
from PySide6.QtQml import QJSValue
|
from PySide6.QtQml import QJSValue
|
||||||
|
|
||||||
|
class InvalidAttributeValueException(Exception): pass
|
||||||
|
|
||||||
class PyJSValue:
|
class PyJSValue:
|
||||||
"""
|
"""
|
||||||
|
@ -38,15 +39,32 @@ class PyJSValue:
|
||||||
elif isinstance(value, PyJSValue):
|
elif isinstance(value, PyJSValue):
|
||||||
# Set property
|
# Set property
|
||||||
self.qjs_value.setProperty(key, value.qjs_value)
|
self.qjs_value.setProperty(key, value.qjs_value)
|
||||||
else:
|
elif isinstance(value, QJSValue):
|
||||||
print('Setting', key, value)
|
|
||||||
self.qjs_value.setProperty(key, value)
|
self.qjs_value.setProperty(key, value)
|
||||||
|
elif type(value) in (int, float, str, bool):
|
||||||
|
self.qjs_value.setProperty(key, QJSValue(value))
|
||||||
|
else:
|
||||||
|
raise InvalidAttributeValueException(f"Invalid value {value} of type {type(value)} being set to {key}.")
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, PyJSValue):
|
||||||
|
return self.qjs_value.equals(other.qjs_value)
|
||||||
|
elif isinstance(other, QJSValue):
|
||||||
|
return self.qjs_value.equals(other)
|
||||||
|
elif type(other) in (int, float, str, bool):
|
||||||
|
return self.qjs_value.equals(QJSValue(other))
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
|
value = None
|
||||||
if self.qjs_value.isCallable():
|
if self.qjs_value.isCallable():
|
||||||
if self._parent is None:
|
if self._parent is None:
|
||||||
return self.qjs_value.call(args)
|
value = self.qjs_value.call(args)
|
||||||
else:
|
else:
|
||||||
return self.qjs_value.callWithInstance(self._parent, args)
|
value = self.qjs_value.callWithInstance(self._parent, args)
|
||||||
else:
|
else:
|
||||||
raise ValueError('Cannot call non-function JS value.')
|
raise InvalidAttributeValueException('Cannot call non-function JS value.')
|
||||||
|
if isinstance(value, QJSValue):
|
||||||
|
value = PyJSValue(value)
|
||||||
|
return value
|
||||||
|
|
13
README.md
13
README.md
|
@ -41,11 +41,6 @@ For all builds, you need [Python 3](https://python.org) with [PySide6](https://p
|
||||||
- To build the snap, you need [snapcraft](https://snapcraft.io) installed.
|
- To build the snap, you need [snapcraft](https://snapcraft.io) installed.
|
||||||
- Run `package-linux.sh`.
|
- Run `package-linux.sh`.
|
||||||
|
|
||||||
|
|
||||||
### Linux
|
|
||||||
|
|
||||||
Run `bash linux/install_local.sh`
|
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
There are several ways to contribute to LogarithmPlotter.
|
There are several ways to contribute to LogarithmPlotter.
|
||||||
|
@ -54,6 +49,14 @@ There are several ways to contribute to LogarithmPlotter.
|
||||||
|
|
||||||
- You can help the development of LogarithmPlotter. In order to get started, take a look at the [wiki](https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_pages).
|
- You can help the development of LogarithmPlotter. In order to get started, take a look at the [wiki](https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_pages).
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
To run LogarithmPlotter's test, use the following:
|
||||||
|
|
||||||
|
- Python
|
||||||
|
- Install `pytest` and `pytest-cov`
|
||||||
|
- Run `pytest --cov`
|
||||||
|
|
||||||
## Legal notice
|
## Legal notice
|
||||||
LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition functions.
|
LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition functions.
|
||||||
Copyright (C) 2021-2024 Ad5001 <mail@ad5001.eu>
|
Copyright (C) 2021-2024 Ad5001 <mail@ad5001.eu>
|
||||||
|
|
10
tests/python/test_config.py
Normal file
10
tests/python/test_config.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class MyTestCase(unittest.TestCase):
|
||||||
|
def test_something(self):
|
||||||
|
self.assertEqual(True, False) # add assertion here
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
0
tests/python/test_helper.py
Normal file
0
tests/python/test_helper.py
Normal file
0
tests/python/test_pyjs.py
Normal file
0
tests/python/test_pyjs.py
Normal file
Loading…
Reference in a new issue