excel2moodle 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- excel2moodle/__init__.py +113 -0
- excel2moodle/__main__.py +31 -0
- excel2moodle/core/__init__.py +13 -0
- excel2moodle/core/category.py +108 -0
- excel2moodle/core/dataStructure.py +140 -0
- excel2moodle/core/etHelpers.py +67 -0
- excel2moodle/core/exceptions.py +20 -0
- excel2moodle/core/globals.py +128 -0
- excel2moodle/core/numericMultiQ.py +76 -0
- excel2moodle/core/parser.py +322 -0
- excel2moodle/core/question.py +106 -0
- excel2moodle/core/questionValidator.py +124 -0
- excel2moodle/core/questionWriter.py +174 -0
- excel2moodle/core/stringHelpers.py +94 -0
- excel2moodle/extra/__init__.py +9 -0
- excel2moodle/extra/equationVerification.py +124 -0
- excel2moodle/ui/__init__.py +1 -0
- excel2moodle/ui/appUi.py +243 -0
- excel2moodle/ui/dialogs.py +80 -0
- excel2moodle/ui/questionPreviewDialog.py +115 -0
- excel2moodle/ui/settings.py +34 -0
- excel2moodle/ui/treewidget.py +65 -0
- excel2moodle/ui/variantDialog.py +132 -0
- excel2moodle/ui/windowDoc.py +35 -0
- excel2moodle/ui/windowEquationChecker.py +187 -0
- excel2moodle-0.3.1.dist-info/METADATA +63 -0
- excel2moodle-0.3.1.dist-info/RECORD +30 -0
- excel2moodle-0.3.1.dist-info/WHEEL +5 -0
- excel2moodle-0.3.1.dist-info/licenses/LICENSE +674 -0
- excel2moodle-0.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
"""This Module hosts the various Dialog Classes, that can be shown from main Window
|
2
|
+
"""
|
3
|
+
from PySide6 import QtWidgets, QtGui
|
4
|
+
import lxml.etree as ET
|
5
|
+
from PySide6.QtSvgWidgets import QGraphicsSvgItem
|
6
|
+
|
7
|
+
from excel2moodle.core.question import Question
|
8
|
+
from excel2moodle.ui.variantDialog import Ui_Dialog
|
9
|
+
from excel2moodle.ui.questionPreviewDialog import Ui_QuestionPrevDialog
|
10
|
+
|
11
|
+
|
12
|
+
class QuestionVariantDialog(QtWidgets.QDialog):
|
13
|
+
def __init__(self, parent, question:Question):
|
14
|
+
super().__init__(parent)
|
15
|
+
self.setWindowTitle("Question Variant Dialog")
|
16
|
+
self.maxVal = question.variants
|
17
|
+
self.ui = Ui_Dialog()
|
18
|
+
self.ui.setupUi(self)
|
19
|
+
self.ui.spinBox.setRange(1, self.maxVal)
|
20
|
+
self.ui.catLabel.setText(f"{question.katName}")
|
21
|
+
self.ui.qLabel.setText(f"{question.name}")
|
22
|
+
self.ui.idLabel.setText(f"{question.id}")
|
23
|
+
|
24
|
+
@property
|
25
|
+
def variant(self):
|
26
|
+
return self.ui.spinBox.value()
|
27
|
+
|
28
|
+
@property
|
29
|
+
def categoryWide(self):
|
30
|
+
return self.ui.checkBox.isChecked()
|
31
|
+
|
32
|
+
|
33
|
+
class QuestinoPreviewDialog(QtWidgets.QDialog):
|
34
|
+
def __init__(self, parent: QtWidgets.QWidget, question:Question) -> None:
|
35
|
+
super().__init__(parent)
|
36
|
+
self.question = question
|
37
|
+
self.ui = Ui_QuestionPrevDialog()
|
38
|
+
self.ui.setupUi(self)
|
39
|
+
self.setWindowTitle(f"Question - {question.id} - Preview")
|
40
|
+
self.setupQuestion()
|
41
|
+
|
42
|
+
def setupQuestion(self)->None:
|
43
|
+
self.ui.qNameLine.setText(self.question.name)
|
44
|
+
self.ui.qTypeLine.setText(self.question.qtype)
|
45
|
+
self.setText()
|
46
|
+
self.setAnswers()
|
47
|
+
self.setPicture()
|
48
|
+
|
49
|
+
def setPicture(self)->None:
|
50
|
+
if hasattr(self.question, "picture") and self.question.picture.ready:
|
51
|
+
self.picScene = QtWidgets.QGraphicsScene(self)
|
52
|
+
self.ui.graphicsView.setScene(self.picScene)
|
53
|
+
path = self.question.picture.path
|
54
|
+
if path.suffix =='.svg':
|
55
|
+
picItem = QGraphicsSvgItem(str(self.question.picture.path))
|
56
|
+
else:
|
57
|
+
pic = QtGui.QPixmap(self.question.picture.path)
|
58
|
+
aspRat = pic.height() // pic.width()
|
59
|
+
width = 400
|
60
|
+
scaleHeight = aspRat * width
|
61
|
+
picItem = QtWidgets.QGraphicsPixmapItem(pic.scaled(width, scaleHeight, QtGui.Qt.AspectRatioMode.KeepAspectRatio))
|
62
|
+
self.picScene.addItem(picItem)
|
63
|
+
else:
|
64
|
+
self.ui.graphicsView.setFixedHeight(1)
|
65
|
+
|
66
|
+
def setText(self)->None:
|
67
|
+
t = []
|
68
|
+
for text in self.question.qtextElements:
|
69
|
+
t.append(ET.tostring(text, encoding='unicode'))
|
70
|
+
|
71
|
+
self.ui.questionText.setText("\n".join(t))
|
72
|
+
|
73
|
+
def setAnswers(self)->None:
|
74
|
+
if self.question.qtype == "NFM":
|
75
|
+
for i,ans in enumerate(self.question.answerVariants):
|
76
|
+
a = ans.find('text').text
|
77
|
+
text = QtWidgets.QLineEdit(a, self )
|
78
|
+
self.ui.answersFormLayout.addRow(f'Answer {i+1}', text)
|
79
|
+
|
80
|
+
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
################################################################################
|
4
|
+
## Form generated from reading UI file 'questionPreviewDialog.ui'
|
5
|
+
##
|
6
|
+
## Created by: Qt User Interface Compiler version 6.8.1
|
7
|
+
##
|
8
|
+
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
9
|
+
################################################################################
|
10
|
+
|
11
|
+
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
12
|
+
QMetaObject, QObject, QPoint, QRect,
|
13
|
+
QSize, QTime, QUrl, Qt)
|
14
|
+
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
15
|
+
QFont, QFontDatabase, QGradient, QIcon,
|
16
|
+
QImage, QKeySequence, QLinearGradient, QPainter,
|
17
|
+
QPalette, QPixmap, QRadialGradient, QTransform)
|
18
|
+
from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialog, QDialogButtonBox,
|
19
|
+
QFormLayout, QFrame, QGraphicsView, QLabel,
|
20
|
+
QLineEdit, QSizePolicy, QVBoxLayout, QWidget)
|
21
|
+
|
22
|
+
class Ui_QuestionPrevDialog(object):
|
23
|
+
def setupUi(self, QuestionPrevDialog):
|
24
|
+
if not QuestionPrevDialog.objectName():
|
25
|
+
QuestionPrevDialog.setObjectName(u"QuestionPrevDialog")
|
26
|
+
QuestionPrevDialog.resize(577, 620)
|
27
|
+
self.verticalLayout = QVBoxLayout(QuestionPrevDialog)
|
28
|
+
self.verticalLayout.setObjectName(u"verticalLayout")
|
29
|
+
self.formLayout = QFormLayout()
|
30
|
+
self.formLayout.setObjectName(u"formLayout")
|
31
|
+
self.formLayout.setLabelAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
|
32
|
+
self.formLayout.setHorizontalSpacing(20)
|
33
|
+
self.formLayout.setVerticalSpacing(5)
|
34
|
+
self.formLayout.setContentsMargins(10, 6, 10, -1)
|
35
|
+
self.questionNameLabel = QLabel(QuestionPrevDialog)
|
36
|
+
self.questionNameLabel.setObjectName(u"questionNameLabel")
|
37
|
+
|
38
|
+
self.formLayout.setWidget(0, QFormLayout.LabelRole, self.questionNameLabel)
|
39
|
+
|
40
|
+
self.qNameLine = QLineEdit(QuestionPrevDialog)
|
41
|
+
self.qNameLine.setObjectName(u"qNameLine")
|
42
|
+
self.qNameLine.setReadOnly(True)
|
43
|
+
|
44
|
+
self.formLayout.setWidget(0, QFormLayout.FieldRole, self.qNameLine)
|
45
|
+
|
46
|
+
self.label = QLabel(QuestionPrevDialog)
|
47
|
+
self.label.setObjectName(u"label")
|
48
|
+
|
49
|
+
self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label)
|
50
|
+
|
51
|
+
self.qTypeLine = QLineEdit(QuestionPrevDialog)
|
52
|
+
self.qTypeLine.setObjectName(u"qTypeLine")
|
53
|
+
self.qTypeLine.setReadOnly(True)
|
54
|
+
|
55
|
+
self.formLayout.setWidget(1, QFormLayout.FieldRole, self.qTypeLine)
|
56
|
+
|
57
|
+
|
58
|
+
self.verticalLayout.addLayout(self.formLayout)
|
59
|
+
|
60
|
+
self.line = QFrame(QuestionPrevDialog)
|
61
|
+
self.line.setObjectName(u"line")
|
62
|
+
self.line.setFrameShape(QFrame.Shape.HLine)
|
63
|
+
self.line.setFrameShadow(QFrame.Shadow.Sunken)
|
64
|
+
|
65
|
+
self.verticalLayout.addWidget(self.line)
|
66
|
+
|
67
|
+
self.questionText = QLabel(QuestionPrevDialog)
|
68
|
+
self.questionText.setObjectName(u"questionText")
|
69
|
+
self.questionText.setWordWrap(True)
|
70
|
+
self.questionText.setMargin(10)
|
71
|
+
|
72
|
+
self.verticalLayout.addWidget(self.questionText)
|
73
|
+
|
74
|
+
self.graphicsView = QGraphicsView(QuestionPrevDialog)
|
75
|
+
self.graphicsView.setObjectName(u"graphicsView")
|
76
|
+
brush = QBrush(QColor(231, 243, 245, 255))
|
77
|
+
brush.setStyle(Qt.SolidPattern)
|
78
|
+
self.graphicsView.setBackgroundBrush(brush)
|
79
|
+
|
80
|
+
self.verticalLayout.addWidget(self.graphicsView)
|
81
|
+
|
82
|
+
self.answersLabel = QLabel(QuestionPrevDialog)
|
83
|
+
self.answersLabel.setObjectName(u"answersLabel")
|
84
|
+
|
85
|
+
self.verticalLayout.addWidget(self.answersLabel)
|
86
|
+
|
87
|
+
self.answersFormLayout = QFormLayout()
|
88
|
+
self.answersFormLayout.setObjectName(u"answersFormLayout")
|
89
|
+
self.answersFormLayout.setContentsMargins(-1, 3, -1, -1)
|
90
|
+
|
91
|
+
self.verticalLayout.addLayout(self.answersFormLayout)
|
92
|
+
|
93
|
+
self.buttonBox = QDialogButtonBox(QuestionPrevDialog)
|
94
|
+
self.buttonBox.setObjectName(u"buttonBox")
|
95
|
+
self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
|
96
|
+
self.buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Close)
|
97
|
+
|
98
|
+
self.verticalLayout.addWidget(self.buttonBox)
|
99
|
+
|
100
|
+
|
101
|
+
self.retranslateUi(QuestionPrevDialog)
|
102
|
+
self.buttonBox.accepted.connect(QuestionPrevDialog.accept)
|
103
|
+
self.buttonBox.rejected.connect(QuestionPrevDialog.reject)
|
104
|
+
|
105
|
+
QMetaObject.connectSlotsByName(QuestionPrevDialog)
|
106
|
+
# setupUi
|
107
|
+
|
108
|
+
def retranslateUi(self, QuestionPrevDialog):
|
109
|
+
QuestionPrevDialog.setWindowTitle(QCoreApplication.translate("QuestionPrevDialog", u"Dialog", None))
|
110
|
+
self.questionNameLabel.setText(QCoreApplication.translate("QuestionPrevDialog", u"Question Name", None))
|
111
|
+
self.label.setText(QCoreApplication.translate("QuestionPrevDialog", u"Question Type", None))
|
112
|
+
self.questionText.setText(QCoreApplication.translate("QuestionPrevDialog", u"QuestionText", None))
|
113
|
+
self.answersLabel.setText(QCoreApplication.translate("QuestionPrevDialog", u"Answers", None))
|
114
|
+
# retranslateUi
|
115
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from PySide6.QtCore import QSettings, QTimer, Signal
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
class Settings(QSettings):
|
5
|
+
shPathChanged = Signal(Path)
|
6
|
+
def __init__(self):
|
7
|
+
super().__init__("jbosse3", "excel2moodle")
|
8
|
+
if self.contains("spreadsheet"):
|
9
|
+
self.sheet = self.value("spreadsheet")
|
10
|
+
try:
|
11
|
+
self.sheet.resolve(strict=True)
|
12
|
+
if self.sheet.is_file():
|
13
|
+
QTimer.singleShot(0,self._emitSpreadsheetChanged)
|
14
|
+
except Exception:
|
15
|
+
return None
|
16
|
+
|
17
|
+
def _emitSpreadsheetChanged(self)->None:
|
18
|
+
self.shPathChanged.emit(self.sheet)
|
19
|
+
print("Emitting Spreadsheet Changed Event")
|
20
|
+
|
21
|
+
|
22
|
+
def get(self, value, default=None):
|
23
|
+
self.value(value, default)
|
24
|
+
|
25
|
+
def set(self, setting, value):
|
26
|
+
self.setValue(setting, value)
|
27
|
+
|
28
|
+
def setSpreadsheet(self, sheet:Path)->None:
|
29
|
+
if isinstance(sheet, Path):
|
30
|
+
self.sheet = sheet.resolve(strict=True)
|
31
|
+
self.setValue("spreadsheet", self.sheet)
|
32
|
+
self.shPathChanged.emit(sheet)
|
33
|
+
return None
|
34
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
from PySide6 import QtWidgets
|
2
|
+
from PySide6.QtCore import Qt
|
3
|
+
from excel2moodle.core.question import Question
|
4
|
+
from excel2moodle.core.dataStructure import Category
|
5
|
+
|
6
|
+
class QuestionItem(QtWidgets.QTreeWidgetItem):
|
7
|
+
def __init__(self, parent, question:Question)->None:
|
8
|
+
super().__init__(parent)
|
9
|
+
self.setData(2,Qt.UserRole, question)
|
10
|
+
self.setText(0, question.id)
|
11
|
+
self.setText(1, question.name)
|
12
|
+
self.setText(2, str(question.points))
|
13
|
+
if hasattr(question, "variants") and question.variants is not None:
|
14
|
+
self.setText(3, str(question.variants))
|
15
|
+
|
16
|
+
|
17
|
+
def getQuestion(self)->Question:
|
18
|
+
return self.data(2, Qt.UserRole)
|
19
|
+
|
20
|
+
class CategoryItem(QtWidgets.QTreeWidgetItem):
|
21
|
+
def __init__(self, parent, category:Category)->None:
|
22
|
+
super().__init__(parent)
|
23
|
+
self.setData(2, Qt.UserRole, category)
|
24
|
+
self.setText(0, category.NAME)
|
25
|
+
self.setText(1, category.desc)
|
26
|
+
self.setText(2, str(category.points))
|
27
|
+
var = self.getMaxVariants()
|
28
|
+
if var != 0:
|
29
|
+
self.setText(3, str(var))
|
30
|
+
|
31
|
+
def iterateChildren(self):
|
32
|
+
for child in range(self.childCount()):
|
33
|
+
yield self.child(child)
|
34
|
+
|
35
|
+
def getMaxVariants(self)->int:
|
36
|
+
count:int=0
|
37
|
+
for child in self.iterateChildren():
|
38
|
+
q = child.getQuestion()
|
39
|
+
if hasattr(q, "variants") and q.variants is not None:
|
40
|
+
count = q.variants if count <= q.variants else count
|
41
|
+
return count
|
42
|
+
|
43
|
+
|
44
|
+
def getCategory(self)->Category:
|
45
|
+
return self.data(2,Qt.UserRole)
|
46
|
+
|
47
|
+
# class SpinBoxDelegate(QtWidgets.QStyledItemDelegate):
|
48
|
+
# def __init__(self, parent=None):
|
49
|
+
# super().__init__(parent)
|
50
|
+
#
|
51
|
+
# def createEditor(self, parent, option, index):
|
52
|
+
# # Create a QSpinBox when the item is being edited
|
53
|
+
# spinbox = QtWidgets.QSpinBox(parent)
|
54
|
+
# spinbox.setMinimum(0)
|
55
|
+
# spinbox.setMaximum(100)
|
56
|
+
# return spinbox
|
57
|
+
#
|
58
|
+
# def setEditorData(self, editor, index):
|
59
|
+
# # Set the current value of the QSpinBox based on the item's data
|
60
|
+
# value = index.model().data(index, Qt.EditRole)
|
61
|
+
# editor.setValue(value)
|
62
|
+
#
|
63
|
+
# def setModelData(self, editor, model, index):
|
64
|
+
# # When editing is done, update the model data with the QSpinBox value
|
65
|
+
# model.setData(index, editor.value(), Qt.EditRole)
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
################################################################################
|
4
|
+
## Form generated from reading UI file 'variantDialog.ui'
|
5
|
+
##
|
6
|
+
## Created by: Qt User Interface Compiler version 6.8.1
|
7
|
+
##
|
8
|
+
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
9
|
+
################################################################################
|
10
|
+
|
11
|
+
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
12
|
+
QMetaObject, QObject, QPoint, QRect,
|
13
|
+
QSize, QTime, QUrl, Qt)
|
14
|
+
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
15
|
+
QFont, QFontDatabase, QGradient, QIcon,
|
16
|
+
QImage, QKeySequence, QLinearGradient, QPainter,
|
17
|
+
QPalette, QPixmap, QRadialGradient, QTransform)
|
18
|
+
from PySide6.QtWidgets import (QAbstractButton, QApplication, QCheckBox, QDialog,
|
19
|
+
QDialogButtonBox, QFormLayout, QFrame, QLabel,
|
20
|
+
QSizePolicy, QSpinBox, QVBoxLayout, QWidget)
|
21
|
+
|
22
|
+
class Ui_Dialog(object):
|
23
|
+
def setupUi(self, Dialog):
|
24
|
+
if not Dialog.objectName():
|
25
|
+
Dialog.setObjectName(u"Dialog")
|
26
|
+
Dialog.resize(400, 300)
|
27
|
+
self.verticalLayout = QVBoxLayout(Dialog)
|
28
|
+
self.verticalLayout.setObjectName(u"verticalLayout")
|
29
|
+
self.formLayout = QFormLayout()
|
30
|
+
self.formLayout.setObjectName(u"formLayout")
|
31
|
+
self.formLayout.setRowWrapPolicy(QFormLayout.RowWrapPolicy.WrapLongRows)
|
32
|
+
self.formLayout.setLabelAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
|
33
|
+
self.formLayout.setFormAlignment(Qt.AlignmentFlag.AlignCenter)
|
34
|
+
self.formLayout.setHorizontalSpacing(20)
|
35
|
+
self.formLayout.setVerticalSpacing(10)
|
36
|
+
self.formLayout.setContentsMargins(-1, -1, 10, -1)
|
37
|
+
self.label = QLabel(Dialog)
|
38
|
+
self.label.setObjectName(u"label")
|
39
|
+
|
40
|
+
self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label)
|
41
|
+
|
42
|
+
self.spinBox = QSpinBox(Dialog)
|
43
|
+
self.spinBox.setObjectName(u"spinBox")
|
44
|
+
|
45
|
+
self.formLayout.setWidget(0, QFormLayout.FieldRole, self.spinBox)
|
46
|
+
|
47
|
+
self.label_2 = QLabel(Dialog)
|
48
|
+
self.label_2.setObjectName(u"label_2")
|
49
|
+
|
50
|
+
self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_2)
|
51
|
+
|
52
|
+
self.checkBox = QCheckBox(Dialog)
|
53
|
+
self.checkBox.setObjectName(u"checkBox")
|
54
|
+
self.checkBox.setChecked(True)
|
55
|
+
|
56
|
+
self.formLayout.setWidget(1, QFormLayout.FieldRole, self.checkBox)
|
57
|
+
|
58
|
+
self.line = QFrame(Dialog)
|
59
|
+
self.line.setObjectName(u"line")
|
60
|
+
self.line.setFrameShape(QFrame.Shape.HLine)
|
61
|
+
self.line.setFrameShadow(QFrame.Shadow.Sunken)
|
62
|
+
|
63
|
+
self.formLayout.setWidget(2, QFormLayout.LabelRole, self.line)
|
64
|
+
|
65
|
+
self.line_2 = QFrame(Dialog)
|
66
|
+
self.line_2.setObjectName(u"line_2")
|
67
|
+
self.line_2.setFrameShape(QFrame.Shape.HLine)
|
68
|
+
self.line_2.setFrameShadow(QFrame.Shadow.Sunken)
|
69
|
+
|
70
|
+
self.formLayout.setWidget(2, QFormLayout.FieldRole, self.line_2)
|
71
|
+
|
72
|
+
self.catText = QLabel(Dialog)
|
73
|
+
self.catText.setObjectName(u"catText")
|
74
|
+
|
75
|
+
self.formLayout.setWidget(3, QFormLayout.LabelRole, self.catText)
|
76
|
+
|
77
|
+
self.catLabel = QLabel(Dialog)
|
78
|
+
self.catLabel.setObjectName(u"catLabel")
|
79
|
+
|
80
|
+
self.formLayout.setWidget(3, QFormLayout.FieldRole, self.catLabel)
|
81
|
+
|
82
|
+
self.qtext = QLabel(Dialog)
|
83
|
+
self.qtext.setObjectName(u"qtext")
|
84
|
+
|
85
|
+
self.formLayout.setWidget(4, QFormLayout.LabelRole, self.qtext)
|
86
|
+
|
87
|
+
self.qLabel = QLabel(Dialog)
|
88
|
+
self.qLabel.setObjectName(u"qLabel")
|
89
|
+
|
90
|
+
self.formLayout.setWidget(4, QFormLayout.FieldRole, self.qLabel)
|
91
|
+
|
92
|
+
self.label_3 = QLabel(Dialog)
|
93
|
+
self.label_3.setObjectName(u"label_3")
|
94
|
+
|
95
|
+
self.formLayout.setWidget(5, QFormLayout.LabelRole, self.label_3)
|
96
|
+
|
97
|
+
self.idLabel = QLabel(Dialog)
|
98
|
+
self.idLabel.setObjectName(u"idLabel")
|
99
|
+
|
100
|
+
self.formLayout.setWidget(5, QFormLayout.FieldRole, self.idLabel)
|
101
|
+
|
102
|
+
|
103
|
+
self.verticalLayout.addLayout(self.formLayout)
|
104
|
+
|
105
|
+
self.buttonBox = QDialogButtonBox(Dialog)
|
106
|
+
self.buttonBox.setObjectName(u"buttonBox")
|
107
|
+
self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
|
108
|
+
self.buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Cancel|QDialogButtonBox.StandardButton.Ok)
|
109
|
+
|
110
|
+
self.verticalLayout.addWidget(self.buttonBox)
|
111
|
+
|
112
|
+
|
113
|
+
self.retranslateUi(Dialog)
|
114
|
+
self.buttonBox.accepted.connect(Dialog.accept)
|
115
|
+
self.buttonBox.rejected.connect(Dialog.reject)
|
116
|
+
|
117
|
+
QMetaObject.connectSlotsByName(Dialog)
|
118
|
+
# setupUi
|
119
|
+
|
120
|
+
def retranslateUi(self, Dialog):
|
121
|
+
Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Dialog", None))
|
122
|
+
self.label.setText(QCoreApplication.translate("Dialog", u"Select question variant", None))
|
123
|
+
self.label_2.setText(QCoreApplication.translate("Dialog", u"Remember for all of this category", None))
|
124
|
+
self.checkBox.setText("")
|
125
|
+
self.catText.setText(QCoreApplication.translate("Dialog", u"Category:", None))
|
126
|
+
self.catLabel.setText(QCoreApplication.translate("Dialog", u"TextLabel", None))
|
127
|
+
self.qtext.setText(QCoreApplication.translate("Dialog", u"Question:", None))
|
128
|
+
self.qLabel.setText(QCoreApplication.translate("Dialog", u"TextLabel", None))
|
129
|
+
self.label_3.setText(QCoreApplication.translate("Dialog", u"ID:", None))
|
130
|
+
self.idLabel.setText(QCoreApplication.translate("Dialog", u"TextLabel", None))
|
131
|
+
# retranslateUi
|
132
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import os
|
2
|
+
import sys
|
3
|
+
from PySide6 import QtWidgets, QtWebEngineWidgets, QtCore
|
4
|
+
from excel2moodle import dirDocumentation
|
5
|
+
|
6
|
+
class DocumentationWindow(QtWidgets.QMainWindow):
|
7
|
+
def __init__(self, documentationDirectory, parent=None):
|
8
|
+
super().__init__(parent)
|
9
|
+
|
10
|
+
self.web_view = QtWebEngineWidgets.QWebEngineView()
|
11
|
+
self.setCentralWidget(self.web_view)
|
12
|
+
|
13
|
+
# Load the HTML documentation
|
14
|
+
|
15
|
+
index_file = os.path.join(documentationDirectory, "index.html")
|
16
|
+
url = QtCore.QUrl.fromLocalFile(index_file)
|
17
|
+
self.web_view.setUrl(url)
|
18
|
+
|
19
|
+
# Set up navigation events
|
20
|
+
self.web_view.page().linkHovered.connect(self.link_hovered)
|
21
|
+
self.web_view.page().loadFinished.connect(self.load_finished)
|
22
|
+
|
23
|
+
def link_hovered(self, url):
|
24
|
+
print(f"Link hovered: {url}")
|
25
|
+
|
26
|
+
def load_finished(self, ok):
|
27
|
+
print(f"Load finished: {ok}")
|
28
|
+
|
29
|
+
if __name__ == "__main__":
|
30
|
+
app = QtWidgets.QApplication(sys.argv)
|
31
|
+
|
32
|
+
window = DocumentationWindow(dirDocumentation)
|
33
|
+
window.show()
|
34
|
+
|
35
|
+
sys.exit(app.exec())
|
@@ -0,0 +1,187 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
################################################################################
|
4
|
+
## Form generated from reading UI file 'equationChecker.ui'
|
5
|
+
##
|
6
|
+
## Created by: Qt User Interface Compiler version 6.8.1
|
7
|
+
##
|
8
|
+
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
9
|
+
################################################################################
|
10
|
+
|
11
|
+
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
12
|
+
QMetaObject, QObject, QPoint, QRect,
|
13
|
+
QSize, QTime, QUrl, Qt)
|
14
|
+
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
15
|
+
QFont, QFontDatabase, QGradient, QIcon,
|
16
|
+
QImage, QKeySequence, QLinearGradient, QPainter,
|
17
|
+
QPalette, QPixmap, QRadialGradient, QTransform)
|
18
|
+
from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QLabel,
|
19
|
+
QLineEdit, QPushButton, QSizePolicy, QSpacerItem,
|
20
|
+
QSpinBox, QTextEdit, QVBoxLayout, QWidget)
|
21
|
+
|
22
|
+
class Ui_EquationChecker(object):
|
23
|
+
def setupUi(self, EquationChecker):
|
24
|
+
if not EquationChecker.objectName():
|
25
|
+
EquationChecker.setObjectName(u"EquationChecker")
|
26
|
+
EquationChecker.resize(1213, 898)
|
27
|
+
icon = QIcon(QIcon.fromTheme(QIcon.ThemeIcon.ListRemove))
|
28
|
+
EquationChecker.setWindowIcon(icon)
|
29
|
+
EquationChecker.setAutoFillBackground(False)
|
30
|
+
self.verticalLayout = QVBoxLayout(EquationChecker)
|
31
|
+
self.verticalLayout.setObjectName(u"verticalLayout")
|
32
|
+
self.gridLayout = QGridLayout()
|
33
|
+
self.gridLayout.setObjectName(u"gridLayout")
|
34
|
+
self.label_6 = QLabel(EquationChecker)
|
35
|
+
self.label_6.setObjectName(u"label_6")
|
36
|
+
font = QFont()
|
37
|
+
font.setPointSize(15)
|
38
|
+
self.label_6.setFont(font)
|
39
|
+
|
40
|
+
self.gridLayout.addWidget(self.label_6, 0, 3, 1, 1)
|
41
|
+
|
42
|
+
self.qNumber = QSpinBox(EquationChecker)
|
43
|
+
self.qNumber.setObjectName(u"qNumber")
|
44
|
+
self.qNumber.setMinimumSize(QSize(150, 0))
|
45
|
+
|
46
|
+
self.gridLayout.addWidget(self.qNumber, 2, 1, 1, 1)
|
47
|
+
|
48
|
+
self.lineFirstResult = QLineEdit(EquationChecker)
|
49
|
+
self.lineFirstResult.setObjectName(u"lineFirstResult")
|
50
|
+
self.lineFirstResult.setEnabled(True)
|
51
|
+
font1 = QFont()
|
52
|
+
font1.setBold(True)
|
53
|
+
self.lineFirstResult.setFont(font1)
|
54
|
+
self.lineFirstResult.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
55
|
+
self.lineFirstResult.setReadOnly(True)
|
56
|
+
|
57
|
+
self.gridLayout.addWidget(self.lineFirstResult, 1, 4, 1, 1)
|
58
|
+
|
59
|
+
self.label_2 = QLabel(EquationChecker)
|
60
|
+
self.label_2.setObjectName(u"label_2")
|
61
|
+
self.label_2.setMinimumSize(QSize(200, 0))
|
62
|
+
|
63
|
+
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
|
64
|
+
|
65
|
+
self.catNumber = QSpinBox(EquationChecker)
|
66
|
+
self.catNumber.setObjectName(u"catNumber")
|
67
|
+
|
68
|
+
self.gridLayout.addWidget(self.catNumber, 1, 1, 1, 1)
|
69
|
+
|
70
|
+
self.label_3 = QLabel(EquationChecker)
|
71
|
+
self.label_3.setObjectName(u"label_3")
|
72
|
+
|
73
|
+
self.gridLayout.addWidget(self.label_3, 1, 3, 1, 1)
|
74
|
+
|
75
|
+
self.label_5 = QLabel(EquationChecker)
|
76
|
+
self.label_5.setObjectName(u"label_5")
|
77
|
+
self.label_5.setFont(font)
|
78
|
+
|
79
|
+
self.gridLayout.addWidget(self.label_5, 0, 1, 1, 1)
|
80
|
+
|
81
|
+
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
82
|
+
|
83
|
+
self.gridLayout.addItem(self.horizontalSpacer, 1, 2, 1, 1)
|
84
|
+
|
85
|
+
self.buttonRunCheck = QPushButton(EquationChecker)
|
86
|
+
self.buttonRunCheck.setObjectName(u"buttonRunCheck")
|
87
|
+
font2 = QFont()
|
88
|
+
font2.setPointSize(12)
|
89
|
+
font2.setBold(True)
|
90
|
+
self.buttonRunCheck.setFont(font2)
|
91
|
+
|
92
|
+
self.gridLayout.addWidget(self.buttonRunCheck, 4, 1, 1, 1)
|
93
|
+
|
94
|
+
self.label_8 = QLabel(EquationChecker)
|
95
|
+
self.label_8.setObjectName(u"label_8")
|
96
|
+
font3 = QFont()
|
97
|
+
font3.setPointSize(12)
|
98
|
+
self.label_8.setFont(font3)
|
99
|
+
|
100
|
+
self.gridLayout.addWidget(self.label_8, 4, 3, 1, 1)
|
101
|
+
|
102
|
+
self.lineCheckResult = QLineEdit(EquationChecker)
|
103
|
+
self.lineCheckResult.setObjectName(u"lineCheckResult")
|
104
|
+
font4 = QFont()
|
105
|
+
font4.setBold(True)
|
106
|
+
font4.setItalic(True)
|
107
|
+
self.lineCheckResult.setFont(font4)
|
108
|
+
self.lineCheckResult.setLayoutDirection(Qt.LayoutDirection.LeftToRight)
|
109
|
+
self.lineCheckResult.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
110
|
+
self.lineCheckResult.setReadOnly(True)
|
111
|
+
|
112
|
+
self.gridLayout.addWidget(self.lineCheckResult, 4, 4, 1, 1)
|
113
|
+
|
114
|
+
self.lineCalculatedRes = QLineEdit(EquationChecker)
|
115
|
+
self.lineCalculatedRes.setObjectName(u"lineCalculatedRes")
|
116
|
+
self.lineCalculatedRes.setFont(font1)
|
117
|
+
self.lineCalculatedRes.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
118
|
+
self.lineCalculatedRes.setReadOnly(True)
|
119
|
+
self.lineCalculatedRes.setClearButtonEnabled(False)
|
120
|
+
|
121
|
+
self.gridLayout.addWidget(self.lineCalculatedRes, 3, 4, 1, 1)
|
122
|
+
|
123
|
+
self.label_4 = QLabel(EquationChecker)
|
124
|
+
self.label_4.setObjectName(u"label_4")
|
125
|
+
|
126
|
+
self.gridLayout.addWidget(self.label_4, 3, 3, 1, 1)
|
127
|
+
|
128
|
+
self.label = QLabel(EquationChecker)
|
129
|
+
self.label.setObjectName(u"label")
|
130
|
+
self.label.setMinimumSize(QSize(100, 0))
|
131
|
+
|
132
|
+
self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
|
133
|
+
|
134
|
+
|
135
|
+
self.verticalLayout.addLayout(self.gridLayout)
|
136
|
+
|
137
|
+
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
|
138
|
+
|
139
|
+
self.verticalLayout.addItem(self.verticalSpacer)
|
140
|
+
|
141
|
+
self.label_7 = QLabel(EquationChecker)
|
142
|
+
self.label_7.setObjectName(u"label_7")
|
143
|
+
self.label_7.setFont(font3)
|
144
|
+
|
145
|
+
self.verticalLayout.addWidget(self.label_7)
|
146
|
+
|
147
|
+
self.line = QFrame(EquationChecker)
|
148
|
+
self.line.setObjectName(u"line")
|
149
|
+
self.line.setFrameShape(QFrame.Shape.HLine)
|
150
|
+
self.line.setFrameShadow(QFrame.Shadow.Sunken)
|
151
|
+
|
152
|
+
self.verticalLayout.addWidget(self.line)
|
153
|
+
|
154
|
+
self.verticalLayout_2 = QVBoxLayout()
|
155
|
+
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
156
|
+
self.textResultsOutput = QTextEdit(EquationChecker)
|
157
|
+
self.textResultsOutput.setObjectName(u"textResultsOutput")
|
158
|
+
|
159
|
+
self.verticalLayout_2.addWidget(self.textResultsOutput)
|
160
|
+
|
161
|
+
|
162
|
+
self.verticalLayout.addLayout(self.verticalLayout_2)
|
163
|
+
|
164
|
+
|
165
|
+
self.retranslateUi(EquationChecker)
|
166
|
+
|
167
|
+
QMetaObject.connectSlotsByName(EquationChecker)
|
168
|
+
# setupUi
|
169
|
+
|
170
|
+
def retranslateUi(self, EquationChecker):
|
171
|
+
EquationChecker.setWindowTitle(QCoreApplication.translate("EquationChecker", u"Equation Checker", None))
|
172
|
+
self.label_6.setText(QCoreApplication.translate("EquationChecker", u"Output", None))
|
173
|
+
self.lineFirstResult.setText(QCoreApplication.translate("EquationChecker", u"0.00", None))
|
174
|
+
self.lineFirstResult.setPlaceholderText(QCoreApplication.translate("EquationChecker", u"waiting", None))
|
175
|
+
self.label_2.setText(QCoreApplication.translate("EquationChecker", u"Question Number", None))
|
176
|
+
self.label_3.setText(QCoreApplication.translate("EquationChecker", u"firstResult from spreadsheet", None))
|
177
|
+
self.label_5.setText(QCoreApplication.translate("EquationChecker", u"Input", None))
|
178
|
+
self.buttonRunCheck.setText(QCoreApplication.translate("EquationChecker", u"Run Check now", None))
|
179
|
+
self.label_8.setText(QCoreApplication.translate("EquationChecker", u"Check", None))
|
180
|
+
self.lineCheckResult.setText("")
|
181
|
+
self.lineCheckResult.setPlaceholderText(QCoreApplication.translate("EquationChecker", u"waiting for check", None))
|
182
|
+
self.lineCalculatedRes.setText(QCoreApplication.translate("EquationChecker", u"0.00", None))
|
183
|
+
self.label_4.setText(QCoreApplication.translate("EquationChecker", u"calculated first Result", None))
|
184
|
+
self.label.setText(QCoreApplication.translate("EquationChecker", u"Category Number", None))
|
185
|
+
self.label_7.setText(QCoreApplication.translate("EquationChecker", u"Calculated Values with corresponding properties", None))
|
186
|
+
# retranslateUi
|
187
|
+
|