Compare commits
No commits in common. "9072e94d14dc3ce0105b4c85e598ff5ad9a492f3" and "52fd95551ca3e010a2bf5a4414001a2ceba3dd42" have entirely different histories.
9072e94d14
...
52fd95551c
12 changed files with 71 additions and 112 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -22,14 +22,15 @@ 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
|
||||||
|
|
|
@ -20,13 +20,13 @@ from shutil import which
|
||||||
__VERSION__ = "0.6.0"
|
__VERSION__ = "0.6.0"
|
||||||
is_release = False
|
is_release = False
|
||||||
|
|
||||||
|
|
||||||
# Check if development version, if so get the date of the latest git patch
|
# Check if development version, if so get the date of the latest git patch
|
||||||
# and append it to the version string.
|
# and append it to the version string.
|
||||||
if not is_release and which('git') is not None:
|
if not is_release and which('git') is not None:
|
||||||
from os.path import realpath, join, dirname, exists
|
from os.path import realpath, join, dirname, exists
|
||||||
from subprocess import check_output
|
from subprocess import check_output
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
# Command to check date of latest git commit
|
# Command to check date of latest git commit
|
||||||
cmd = ['git', 'log', '--format=%ci', '-n 1']
|
cmd = ['git', 'log', '--format=%ci', '-n 1']
|
||||||
cwd = realpath(join(dirname(__file__), '..')) # Root AccountFree directory.
|
cwd = realpath(join(dirname(__file__), '..')) # Root AccountFree directory.
|
||||||
|
@ -41,5 +41,4 @@ if not is_release and which('git') is not None:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from .logarithmplotter import run
|
from .logarithmplotter import run
|
||||||
|
|
||||||
run()
|
run()
|
||||||
|
|
|
@ -87,6 +87,7 @@ def run():
|
||||||
icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom")))
|
icon_fallbacks.append(path.realpath(path.join(base_icon_path, "settings", "custom")))
|
||||||
QIcon.setFallbackSearchPaths(icon_fallbacks);
|
QIcon.setFallbackSearchPaths(icon_fallbacks);
|
||||||
|
|
||||||
|
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
|
||||||
app = QApplication(argv)
|
app = QApplication(argv)
|
||||||
app.setApplicationName("LogarithmPlotter")
|
app.setApplicationName("LogarithmPlotter")
|
||||||
app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop")
|
app.setDesktopFileName("eu.ad5001.LogarithmPlotter.desktop")
|
||||||
|
@ -103,10 +104,10 @@ def run():
|
||||||
app.installTranslator(translator);
|
app.installTranslator(translator);
|
||||||
|
|
||||||
# Installing macOS file handler.
|
# Installing macOS file handler.
|
||||||
macos_file_open_handler = None
|
macOSFileOpenHandler = None
|
||||||
if platform == "darwin":
|
if platform == "darwin":
|
||||||
macos_file_open_handler = native.MacOSFileOpenHandler()
|
macOSFileOpenHandler = native.MacOSFileOpenHandler()
|
||||||
app.installEventFilter(macos_file_open_handler)
|
app.installEventFilter(macOSFileOpenHandler)
|
||||||
|
|
||||||
engine = QQmlApplicationEngine()
|
engine = QQmlApplicationEngine()
|
||||||
global tmpfile
|
global tmpfile
|
||||||
|
@ -137,7 +138,7 @@ def run():
|
||||||
chdir(path.dirname(path.realpath(__file__)))
|
chdir(path.dirname(path.realpath(__file__)))
|
||||||
|
|
||||||
if platform == "darwin":
|
if platform == "darwin":
|
||||||
macos_file_open_handler.init_io(js_globals.Modules.IO)
|
macOSFileOpenHandler.init_io(js_globals.Modules.IO)
|
||||||
|
|
||||||
# Check for LaTeX installation if LaTeX support is enabled
|
# Check for LaTeX installation if LaTeX support is enabled
|
||||||
if config.getSetting("enable_latex"):
|
if config.getSetting("enable_latex"):
|
||||||
|
|
|
@ -21,6 +21,7 @@ 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,
|
||||||
|
@ -37,7 +38,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",
|
||||||
|
@ -53,48 +54,40 @@ 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 path.join(path.expanduser("~"), ".config", "LogarithmPlotter"),
|
||||||
if "XDG_CONFIG_HOME" in environ else
|
|
||||||
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(file, 'w', -1, 'utf8')
|
write_file = open(CONFIG_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.
|
||||||
|
@ -108,10 +101,9 @@ def getSetting(namespace):
|
||||||
setting = setting[name]
|
setting = setting[name]
|
||||||
else:
|
else:
|
||||||
# return namespace # Return original name
|
# return namespace # Return original name
|
||||||
raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}")
|
raise ValueError('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.
|
||||||
|
@ -125,6 +117,6 @@ def setSetting(namespace, data):
|
||||||
if name in setting:
|
if name in setting:
|
||||||
setting = setting[name]
|
setting = setting[name]
|
||||||
else:
|
else:
|
||||||
raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}")
|
raise ValueError('Setting {} doesn\'t exist. Debug: {}, {}'.format(namespace, setting, name))
|
||||||
else:
|
else:
|
||||||
setting[name] = data
|
setting[name] = data
|
||||||
|
|
|
@ -32,9 +32,6 @@ 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)
|
||||||
|
@ -97,16 +94,16 @@ 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.")
|
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__)))
|
||||||
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
|
||||||
msg = QCoreApplication.translate('main', 'Could not open file "{}":\n{}')
|
QMessageBox.warning(None, 'LogarithmPlotter',
|
||||||
QMessageBox.warning(None, 'LogarithmPlotter', msg.format(filename, e), QMessageBox.Ok) # Cannot parse file
|
QCoreApplication.translate('main', 'Could not open file "{}":\n{}').format(filename,
|
||||||
|
e),
|
||||||
|
QMessageBox.Ok) # Cannot parse file
|
||||||
else:
|
else:
|
||||||
msg = QCoreApplication.translate('main', 'Could not open file: "{}"\nFile does not exist.')
|
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', msg.format(filename), QMessageBox.Ok) # Cannot parse file
|
|
||||||
try:
|
try:
|
||||||
chdir(path.dirname(path.realpath(__file__)))
|
chdir(path.dirname(path.realpath(__file__)))
|
||||||
except NotADirectoryError as e:
|
except NotADirectoryError as e:
|
||||||
|
@ -134,6 +131,7 @@ 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)
|
||||||
|
@ -161,8 +159,9 @@ class Helper(QObject):
|
||||||
"""
|
"""
|
||||||
Returns the version info about Qt, PySide6 & Python
|
Returns the version info about Qt, PySide6 & Python
|
||||||
"""
|
"""
|
||||||
msg = QCoreApplication.translate('main', "Built with PySide6 (Qt) v{} and python v{}")
|
return QCoreApplication.translate('main', "Built with PySide6 (Qt) v{} and python v{}").format(PySide6_version,
|
||||||
return msg.format(PySide6_version, sys_version.split("\n")[0])
|
sys_version.split(
|
||||||
|
"\n")[0])
|
||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def fetchChangelog(self):
|
def fetchChangelog(self):
|
||||||
|
|
|
@ -18,13 +18,11 @@
|
||||||
|
|
||||||
from PySide6.QtQml import QJSValue
|
from PySide6.QtQml import QJSValue
|
||||||
|
|
||||||
class InvalidAttributeValueException(Exception): pass
|
|
||||||
|
|
||||||
class PyJSValue:
|
class PyJSValue:
|
||||||
"""
|
"""
|
||||||
Wrapper to provide easy way to interact with JavaScript values in Python directly.
|
Wrapper to provide easy way to interact with JavaScript values in Python directly.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, js_value: QJSValue, parent: QJSValue = None):
|
def __init__(self, js_value: QJSValue, parent: QJSValue = None):
|
||||||
self.qjs_value = js_value
|
self.qjs_value = js_value
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
|
@ -39,32 +37,16 @@ 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)
|
||||||
elif isinstance(value, QJSValue):
|
else:
|
||||||
|
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:
|
||||||
value = self.qjs_value.call(args)
|
return self.qjs_value.call(args)
|
||||||
else:
|
else:
|
||||||
value = self.qjs_value.callWithInstance(self._parent, args)
|
return self.qjs_value.callWithInstance(self._parent, args)
|
||||||
else:
|
else:
|
||||||
raise InvalidAttributeValueException('Cannot call non-function JS value.')
|
raise ValueError('Cannot call non-function JS value.')
|
||||||
if isinstance(value, QJSValue):
|
|
||||||
value = PyJSValue(value)
|
|
||||||
return value
|
|
||||||
|
|
|
@ -66,11 +66,11 @@ class Latex(QObject):
|
||||||
self.tempdir = tempdir
|
self.tempdir = tempdir
|
||||||
|
|
||||||
@Property(bool)
|
@Property(bool)
|
||||||
def latexSupported(self) -> bool:
|
def latexSupported(self):
|
||||||
return LATEX_PATH is not None and DVIPNG_PATH is not None
|
return LATEX_PATH is not None and DVIPNG_PATH is not None
|
||||||
|
|
||||||
@Slot(result=bool)
|
@Slot(result=bool)
|
||||||
def checkLatexInstallation(self) -> bool:
|
def checkLatexInstallation(self):
|
||||||
"""
|
"""
|
||||||
Checks if the current latex installation is valid.
|
Checks if the current latex installation is valid.
|
||||||
"""
|
"""
|
||||||
|
@ -78,22 +78,19 @@ class Latex(QObject):
|
||||||
if LATEX_PATH is None:
|
if LATEX_PATH is None:
|
||||||
print("No Latex installation found.")
|
print("No Latex installation found.")
|
||||||
if "--test-build" not in argv:
|
if "--test-build" not in argv:
|
||||||
msg = QCoreApplication.translate("latex",
|
QMessageBox.warning(None, "LogarithmPlotter - Latex setup",
|
||||||
"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/.")
|
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", msg)
|
|
||||||
valid_install = False
|
valid_install = False
|
||||||
elif DVIPNG_PATH is None:
|
elif DVIPNG_PATH is None:
|
||||||
print("DVIPNG not found.")
|
print("DVIPNG not found.")
|
||||||
if "--test-build" not in argv:
|
if "--test-build" not in argv:
|
||||||
msg = QCoreApplication.translate("latex",
|
QMessageBox.warning(None, "LogarithmPlotter - Latex setup", QCoreApplication.translate("latex", "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.")
|
|
||||||
QMessageBox.warning(None, "LogarithmPlotter - Latex setup", msg)
|
|
||||||
valid_install = False
|
valid_install = False
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self.render("", 14, QColor(0, 0, 0, 255))
|
self.render("", 14, QColor(0, 0, 0, 255))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
valid_install = False # Should have sent an error message if failed to render
|
valid_install = False # Should have sent an error message if failed to render
|
||||||
return valid_install
|
return valid_install
|
||||||
|
|
||||||
@Slot(str, float, QColor, result=str)
|
@Slot(str, float, QColor, result=str)
|
||||||
|
@ -122,9 +119,9 @@ class Latex(QObject):
|
||||||
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
|
# 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()}'
|
return f'{export_path}.png,{img.width()},{img.height()}'
|
||||||
|
|
||||||
@Slot(str, float, QColor, result=str)
|
@Slot(str, float, QColor, result=str)
|
||||||
def findPrerendered(self, latex_markup: str, font_size: float, color: QColor) -> str:
|
def findPrerendered(self, latex_markup: str, font_size: float, color: QColor):
|
||||||
"""
|
"""
|
||||||
Finds a prerendered image and returns its data if possible, and an empty string if not.
|
Finds a prerendered image and returns its data if possible, and an empty string if not.
|
||||||
"""
|
"""
|
||||||
|
@ -134,7 +131,8 @@ class Latex(QObject):
|
||||||
img = QImage(export_path)
|
img = QImage(export_path)
|
||||||
data = f'{export_path}.png,{img.width()},{img.height()}'
|
data = f'{export_path}.png,{img.width()},{img.height()}'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def create_export_path(self, latex_markup: str, font_size: float, color: QColor):
|
def create_export_path(self, latex_markup: str, font_size: float, color: QColor):
|
||||||
"""
|
"""
|
||||||
Standardizes export path for renders.
|
Standardizes export path for renders.
|
||||||
|
@ -142,6 +140,7 @@ class Latex(QObject):
|
||||||
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()}')
|
export_path = path.join(self.tempdir.name, f'{markup_hash}_{int(font_size)}_{color.rgb()}')
|
||||||
return markup_hash, export_path
|
return markup_hash, export_path
|
||||||
|
|
||||||
|
|
||||||
def create_latex_doc(self, export_path: str, latex_markup: str):
|
def create_latex_doc(self, export_path: str, latex_markup: str):
|
||||||
"""
|
"""
|
||||||
|
@ -184,18 +183,16 @@ class Latex(QObject):
|
||||||
"""
|
"""
|
||||||
Runs a subprocess and handles exceptions and messages them to the user.
|
Runs a subprocess and handles exceptions and messages them to the user.
|
||||||
"""
|
"""
|
||||||
cmd = " ".join(process)
|
|
||||||
proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir.name)
|
proc = Popen(process, stdout=PIPE, stderr=PIPE, cwd=self.tempdir.name)
|
||||||
try:
|
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:
|
if proc.returncode != 0:
|
||||||
# Process errored
|
# Process errored
|
||||||
output = str(out, 'utf8') + "\n" + str(err, 'utf8')
|
output = str(out, 'utf8') + "\n" + str(err, 'utf8')
|
||||||
msg = QCoreApplication.translate("latex",
|
QMessageBox.warning(None, "LogarithmPlotter - 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.")
|
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.")
|
||||||
msg = msg.format(cmd, proc.returncode, output)
|
.format(" ".join(process), proc.returncode, output))
|
||||||
QMessageBox.warning(None, "LogarithmPlotter - Latex", msg)
|
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')))
|
||||||
raise Exception(f"{cmd} process exited with return code {str(proc.returncode)}:\n{str(out, 'utf8')}\n{str(err, 'utf8')}")
|
|
||||||
except TimeoutExpired as e:
|
except TimeoutExpired as e:
|
||||||
# Process timed out
|
# Process timed out
|
||||||
proc.kill()
|
proc.kill()
|
||||||
|
@ -205,14 +202,14 @@ class Latex(QObject):
|
||||||
for pkg in PACKAGES:
|
for pkg in PACKAGES:
|
||||||
if f'{pkg}.sty' in output:
|
if f'{pkg}.sty' in output:
|
||||||
# Package missing.
|
# Package missing.
|
||||||
msg = QCoreApplication.translate("latex",
|
QMessageBox.warning(None, "LogarithmPlotter - Latex",
|
||||||
"Your LaTeX installation does not include some required packages:\n\n- {} (https://ctan.org/pkg/{})\n\nMake sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter.")
|
QCoreApplication.translate("latex", "Your LaTeX installation does not include some required packages:\n\n- {} (https://ctan.org/pkg/{})\n\nMake sure said package is installed, or disable the LaTeX rendering in LogarithmPlotter.")
|
||||||
QMessageBox.warning(None, "LogarithmPlotter - Latex", msg.format(pkg, pkg))
|
.format(pkg, pkg))
|
||||||
raise Exception("Latex: Missing package " + pkg)
|
raise Exception("Latex: Missing package " + pkg)
|
||||||
msg = QCoreApplication.translate("latex",
|
QMessageBox.warning(None, "LogarithmPlotter - 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.")
|
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.")
|
||||||
QMessageBox.warning(None, "LogarithmPlotter - Latex", msg.format(cmd, output))
|
.format(" ".join(process), output))
|
||||||
raise Exception(f"{cmd} process timed out:\n{output}")
|
raise Exception(" ".join(process) + " process timed out:\n" + output)
|
||||||
|
|
||||||
def cleanup(self, export_path):
|
def cleanup(self, export_path):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -53,8 +53,9 @@ class UpdateCheckerRunnable(QRunnable):
|
||||||
current_version_tuple = self.current_version.split(".")
|
current_version_tuple = self.current_version.split(".")
|
||||||
is_version_newer = version_tuple > current_version_tuple
|
is_version_newer = version_tuple > current_version_tuple
|
||||||
if is_version_newer:
|
if is_version_newer:
|
||||||
msg_text = QCoreApplication.translate("update", "An update for LogarithmPlotter (v{}) is available.")
|
msg_text = QCoreApplication.translate("update",
|
||||||
msg_text = msg_text.format(version)
|
"An update for LogarithPlotter (v{}) is available.").format(
|
||||||
|
version)
|
||||||
update_available = True
|
update_available = True
|
||||||
else:
|
else:
|
||||||
show_alert = False
|
show_alert = False
|
||||||
|
@ -62,11 +63,11 @@ class UpdateCheckerRunnable(QRunnable):
|
||||||
|
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
msg_text = QCoreApplication.translate("update",
|
msg_text = QCoreApplication.translate("update",
|
||||||
"Could not fetch update information: Server error {}.")
|
"Could not fetch update information: Server error {}.").format(
|
||||||
msg_text = msg_text.format(str(e.code))
|
str(e.code))
|
||||||
except URLError as e:
|
except URLError as e:
|
||||||
msg_text = QCoreApplication.translate("update", "Could not fetch update information: {}.")
|
msg_text = QCoreApplication.translate("update", "Could not fetch update information: {}.").format(
|
||||||
msg_text = msg_text.format(str(e.reason))
|
str(e.reason))
|
||||||
self.callback.got_update_info.emit(show_alert, msg_text, update_available)
|
self.callback.got_update_info.emit(show_alert, msg_text, update_available)
|
||||||
|
|
||||||
|
|
||||||
|
|
13
README.md
13
README.md
|
@ -41,6 +41,11 @@ 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.
|
||||||
|
@ -49,14 +54,6 @@ 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>
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import unittest
|
|
||||||
|
|
||||||
|
|
||||||
class MyTestCase(unittest.TestCase):
|
|
||||||
def test_something(self):
|
|
||||||
self.assertEqual(True, False) # add assertion here
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
Loading…
Reference in a new issue