excel2moodle 0.3.3__py3-none-any.whl → 0.3.5__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.
@@ -1,16 +1,18 @@
1
- """This Module hosts the various Dialog Classes, that can be shown from main Window
2
- """
3
- from PySide6 import QtWidgets, QtGui
1
+ """This Module hosts the various Dialog Classes, that can be shown from main Window."""
2
+
4
3
  import lxml.etree as ET
4
+ from PySide6 import QtGui, QtWidgets
5
5
  from PySide6.QtSvgWidgets import QGraphicsSvgItem
6
6
 
7
+ from excel2moodle import e2mMetadata
8
+ from excel2moodle.core.globals import XMLTags
7
9
  from excel2moodle.core.question import Question
8
- from excel2moodle.ui.variantDialog import Ui_Dialog
9
10
  from excel2moodle.ui.questionPreviewDialog import Ui_QuestionPrevDialog
11
+ from excel2moodle.ui.variantDialog import Ui_Dialog
10
12
 
11
13
 
12
14
  class QuestionVariantDialog(QtWidgets.QDialog):
13
- def __init__(self, parent, question:Question):
15
+ def __init__(self, parent, question: Question) -> None:
14
16
  super().__init__(parent)
15
17
  self.setWindowTitle("Question Variant Dialog")
16
18
  self.maxVal = question.variants
@@ -31,50 +33,101 @@ class QuestionVariantDialog(QtWidgets.QDialog):
31
33
 
32
34
 
33
35
  class QuestinoPreviewDialog(QtWidgets.QDialog):
34
- def __init__(self, parent: QtWidgets.QWidget, question:Question) -> None:
36
+ def __init__(self, parent: QtWidgets.QWidget, question: Question) -> None:
35
37
  super().__init__(parent)
36
38
  self.question = question
37
39
  self.ui = Ui_QuestionPrevDialog()
38
40
  self.ui.setupUi(self)
41
+ self.setModal(True)
39
42
  self.setWindowTitle(f"Question - {question.id} - Preview")
40
43
  self.setupQuestion()
41
44
 
42
- def setupQuestion(self)->None:
45
+ def setupQuestion(self) -> None:
43
46
  self.ui.qNameLine.setText(self.question.name)
44
47
  self.ui.qTypeLine.setText(self.question.qtype)
45
48
  self.setText()
46
49
  self.setAnswers()
47
50
  self.setPicture()
48
51
 
49
- def setPicture(self)->None:
52
+ def setPicture(self) -> None:
50
53
  if hasattr(self.question, "picture") and self.question.picture.ready:
51
54
  self.picScene = QtWidgets.QGraphicsScene(self)
52
55
  self.ui.graphicsView.setScene(self.picScene)
53
56
  path = self.question.picture.path
54
- if path.suffix =='.svg':
57
+ if path.suffix == ".svg":
55
58
  picItem = QGraphicsSvgItem(str(self.question.picture.path))
56
59
  else:
57
60
  pic = QtGui.QPixmap(self.question.picture.path)
58
61
  aspRat = pic.height() // pic.width()
59
62
  width = 400
60
63
  scaleHeight = aspRat * width
61
- picItem = QtWidgets.QGraphicsPixmapItem(pic.scaled(width, scaleHeight, QtGui.Qt.AspectRatioMode.KeepAspectRatio))
64
+ picItem = QtWidgets.QGraphicsPixmapItem(
65
+ pic.scaled(
66
+ width, scaleHeight, QtGui.Qt.AspectRatioMode.KeepAspectRatio
67
+ )
68
+ )
62
69
  self.picScene.addItem(picItem)
63
70
  else:
64
71
  self.ui.graphicsView.setFixedHeight(1)
65
72
 
66
- def setText(self)->None:
73
+ def setText(self) -> None:
67
74
  t = []
68
75
  for text in self.question.qtextParagraphs:
69
- t.append(ET.tostring(text, encoding='unicode'))
70
- t.append(ET.tostring(self.question.bulletList, encoding='unicode'))
76
+ t.append(ET.tostring(text, encoding="unicode"))
77
+ if self.question.bulletList is not None:
78
+ t.append(ET.tostring(self.question.bulletList, encoding="unicode"))
71
79
  self.ui.questionText.setText("\n".join(t))
72
80
 
73
- def setAnswers(self)->None:
81
+ def setAnswers(self) -> None:
74
82
  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)
83
+ for i, ans in enumerate(self.question.answerVariants):
84
+ a = ans.find("text").text
85
+ text = QtWidgets.QLineEdit(a, self)
86
+ self.ui.answersFormLayout.addRow(f"Answer {i + 1}", text)
87
+
88
+ elif self.question.qtype == "NF":
89
+ ans = self.question.element.find(XMLTags.ANSWER)
90
+ a = ans.find("text").text
91
+ text = QtWidgets.QLineEdit(a, self)
92
+ self.ui.answersFormLayout.addRow("Result", text)
93
+
94
+ elif self.question.qtype == "MC":
95
+ for i, ans in enumerate(self.question.element.findall(XMLTags.ANSWER)):
96
+ a = ans.find("text").text
97
+ frac = ans.get("fraction")
98
+ text = QtWidgets.QLineEdit(a, self)
99
+ self.ui.answersFormLayout.addRow(f"Fraction: {frac}", text)
100
+
101
+
102
+ class AboutDialog(QtWidgets.QMessageBox):
103
+ def __init__(self, parent: QtWidgets.QWidget) -> None:
104
+ super().__init__(parent)
105
+ self.setWindowTitle(f"About {e2mMetadata['name']}")
106
+ self.setIcon(QtWidgets.QMessageBox.Information)
107
+ self.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Close)
79
108
 
109
+ self.aboutMessage: str = f"""
110
+ <h1> About {e2mMetadata["name"]}</h1><br>
111
+ <p style="text-align:center">
80
112
 
113
+ <b><a href="{e2mMetadata["homepage"]}">{e2mMetadata["name"]}</a> - {e2mMetadata["description"]}</b>
114
+ </p>
115
+ <p style="text-align:center">
116
+ The documentation can be found under <b>
117
+ <a href="{e2mMetadata["documentation"]}">{e2mMetadata["documentation"]}</a></b>
118
+ </br>
119
+ </p>
120
+ <p style="text-align:center">
121
+ This project is maintained by {e2mMetadata["author"]}.
122
+ <br>
123
+ Development takes place at <a href="{e2mMetadata["homepage"]}"> GitLab: {e2mMetadata["homepage"]}</a>
124
+ contributions are very welcome
125
+ </br>
126
+ If you encounter any issues please report them under the repositories issues page.
127
+ </br>
128
+ </p>
129
+ <p style="text-align:center">
130
+ <i>This project is published under {e2mMetadata["license"]}, you are welcome, to share, modify and reuse the code.</i>
131
+ </p>
132
+ """
133
+ self.setText(self.aboutMessage)
@@ -1,35 +1,122 @@
1
- from PySide6.QtCore import QSettings, QTimer, Signal
1
+ """Settings module provides the adjusted subclass of ``PySide6.QtCore.QSettings``."""
2
+
3
+ import logging
4
+ from enum import StrEnum
2
5
  from pathlib import Path
6
+ from typing import Literal, overload
7
+
8
+ from PySide6.QtCore import QSettings, QTimer, Signal
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class SettingsKey(StrEnum):
14
+ def __new__(
15
+ cls,
16
+ key: str,
17
+ typ: type,
18
+ default: str | float | Path | bool | None,
19
+ ):
20
+ """Define new settings class."""
21
+ obj = str.__new__(cls, key)
22
+ obj._value_ = key
23
+ obj._default_ = default
24
+ obj._typ_ = typ
25
+ return obj
26
+
27
+ @property
28
+ def default(self) -> str | int | float | Path | bool | None:
29
+ """Get default value for the key."""
30
+ return self._default_
31
+
32
+ def typ(self) -> type:
33
+ """Get default value for the key."""
34
+ return self._typ_
35
+
36
+ QUESTIONVARIANT = "testgen/defaultQuestionVariant", int, 0
37
+ INCLUDEINCATS = "testgen/includeCats", bool, False
38
+ PARSERNF_TOLERANCE = "parser/nf/tolerance", int, 1
39
+ PICTURESUBFOLDER = "core/pictureSubFolder", str, "Abbildungen"
40
+ PICTUREFOLDER = "core/pictureFolder", Path, None
41
+ SPREADSHEETFOLDER = "core/spreadsheetFolder", Path, None
42
+ LOGLEVEL = "core/loglevel", str, "INFO"
43
+ LOGFILE = "core/logfile", str, "excel2moodleLogFile.log"
44
+
3
45
 
4
46
  class Settings(QSettings):
47
+ """Settings for Excel2moodle."""
48
+
5
49
  shPathChanged = Signal(Path)
6
- def __init__(self):
50
+
51
+ def __init__(self) -> None:
52
+ """Instantiate the settings."""
7
53
  super().__init__("jbosse3", "excel2moodle")
8
- if self.contains("core/spreadsheet"):
9
- self.sheet = self.value("core/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
54
+ if self.contains(SettingsKey.SPREADSHEETFOLDER):
55
+ self.sheet = self.get(SettingsKey.SPREADSHEETFOLDER)
56
+ if self.sheet.is_file():
57
+ QTimer.singleShot(0, self._emitSpreadsheetChanged)
16
58
 
17
- def _emitSpreadsheetChanged(self)->None:
59
+ def _emitSpreadsheetChanged(self) -> None:
18
60
  self.shPathChanged.emit(self.sheet)
19
- print("Emitting Spreadsheet Changed Event")
20
-
21
61
 
22
- def get(self, value, default=None):
23
- return self.value(value, default)
62
+ @overload
63
+ def get(
64
+ self,
65
+ value: Literal[SettingsKey.QUESTIONVARIANT, SettingsKey.PARSERNF_TOLERANCE],
66
+ ) -> int: ...
67
+ @overload
68
+ def get(self, value: Literal[SettingsKey.INCLUDEINCATS]) -> bool: ...
69
+ @overload
70
+ def get(
71
+ self,
72
+ value: Literal[
73
+ SettingsKey.PICTURESUBFOLDER, SettingsKey.LOGLEVEL, SettingsKey.LOGFILE
74
+ ],
75
+ ) -> str: ...
76
+ @overload
77
+ def get(
78
+ self,
79
+ value: Literal[SettingsKey.PICTUREFOLDER, SettingsKey.SPREADSHEETFOLDER],
80
+ ) -> Path: ...
24
81
 
82
+ def get(self, value: SettingsKey):
83
+ """Get the typesafe settings value."""
84
+ logger.debug("entering get method. searched typ: %s", value.typ())
85
+ if value.typ() is Path:
86
+ logger.debug("trying to acess a path object from settings")
87
+ path = self.value(value, defaultValue=value.default)
88
+ try:
89
+ path.resolve(strict=True)
90
+ except ValueError:
91
+ logger.warning(
92
+ f"The settingsvalue {value} couldn't be fetched with correct typ",
93
+ )
94
+ return value.default
95
+ return path
96
+ raw = self.value(value, defaultValue=value.default, type=value.typ())
97
+ logger.debug("read a settings Value: %s of type: %s", value, value.typ())
98
+ try:
99
+ return value.typ()(raw)
100
+ except (ValueError, TypeError):
101
+ logger.warning(
102
+ f"The settingsvalue {value} couldn't be fetched with correct typ",
103
+ )
104
+ return value.default
25
105
 
26
- def set(self, setting, value):
27
- self.setValue(setting, value)
106
+ def set(self, settingKey: SettingsKey, value: float | bool | Path | str) -> None:
107
+ """Set the setting to value."""
108
+ # if isinstance(value, SettingsKey.type):
109
+ self.setValue(settingKey, value)
110
+ logger.info("Saved the Setting %s = %s", settingKey, value)
111
+ # else:
112
+ # logger.error("trying to save setting with wrong type not possible")
28
113
 
29
- def setSpreadsheet(self, sheet:Path)->None:
114
+ def setSpreadsheet(self, sheet: Path) -> None:
115
+ """Save spreadsheet path and emit the changed event."""
30
116
  if isinstance(sheet, Path):
31
117
  self.sheet = sheet.resolve(strict=True)
32
- self.setValue("core/spreadsheet", self.sheet)
118
+ logpath = str(self.sheet.parent / "excel2moodleLogFile.log")
119
+ self.set(SettingsKey.LOGFILE, logpath)
120
+ self.set(SettingsKey.SPREADSHEETFOLDER, self.sheet)
33
121
  self.shPathChanged.emit(sheet)
34
- return None
35
-
122
+ return
@@ -1,24 +1,27 @@
1
1
  from PySide6 import QtWidgets
2
2
  from PySide6.QtCore import Qt
3
- from excel2moodle.core.question import Question
3
+
4
4
  from excel2moodle.core.dataStructure import Category
5
+ from excel2moodle.core.question import Question
6
+
5
7
 
6
8
  class QuestionItem(QtWidgets.QTreeWidgetItem):
7
- def __init__(self, parent, question:Question)->None:
9
+ def __init__(self, parent, question: Question) -> None:
8
10
  super().__init__(parent)
9
- self.setData(2,Qt.UserRole, question)
11
+ self.setData(2, Qt.UserRole, question)
10
12
  self.setText(0, question.id)
11
13
  self.setText(1, question.name)
12
14
  self.setText(2, str(question.points))
13
15
  if hasattr(question, "variants") and question.variants is not None:
14
16
  self.setText(3, str(question.variants))
15
17
 
16
-
17
- def getQuestion(self)->Question:
18
+ def getQuestion(self) -> Question:
19
+ """Return the question Object the QTreeWidgetItem represents."""
18
20
  return self.data(2, Qt.UserRole)
19
21
 
22
+
20
23
  class CategoryItem(QtWidgets.QTreeWidgetItem):
21
- def __init__(self, parent, category:Category)->None:
24
+ def __init__(self, parent, category: Category) -> None:
22
25
  super().__init__(parent)
23
26
  self.setData(2, Qt.UserRole, category)
24
27
  self.setText(0, category.NAME)
@@ -32,17 +35,17 @@ class CategoryItem(QtWidgets.QTreeWidgetItem):
32
35
  for child in range(self.childCount()):
33
36
  yield self.child(child)
34
37
 
35
- def getMaxVariants(self)->int:
36
- count:int=0
38
+ def getMaxVariants(self) -> int:
39
+ count: int = 0
37
40
  for child in self.iterateChildren():
38
41
  q = child.getQuestion()
39
42
  if hasattr(q, "variants") and q.variants is not None:
40
43
  count = q.variants if count <= q.variants else count
41
44
  return count
42
45
 
46
+ def getCategory(self) -> Category:
47
+ return self.data(2, Qt.UserRole)
43
48
 
44
- def getCategory(self)->Category:
45
- return self.data(2,Qt.UserRole)
46
49
 
47
50
  # class SpinBoxDelegate(QtWidgets.QStyledItemDelegate):
48
51
  # def __init__(self, parent=None):
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'mainWindow.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.8.3
6
+ ## Created by: Qt User Interface Compiler version 6.9.0
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -52,9 +52,6 @@ class Ui_MoodleTestGenerator(object):
52
52
  self.actionAbout.setObjectName(u"actionAbout")
53
53
  icon5 = QIcon(QIcon.fromTheme(u"help-about"))
54
54
  self.actionAbout.setIcon(icon5)
55
- self.actionDocumentation = QAction(MoodleTestGenerator)
56
- self.actionDocumentation.setObjectName(u"actionDocumentation")
57
- self.actionDocumentation.setIcon(icon5)
58
55
  self.actionSetting = QAction(MoodleTestGenerator)
59
56
  self.actionSetting.setObjectName(u"actionSetting")
60
57
  icon6 = QIcon(QIcon.fromTheme(u"preferences-system"))
@@ -136,7 +133,7 @@ class Ui_MoodleTestGenerator(object):
136
133
  self.label_6 = QLabel(self.mainWidget)
137
134
  self.label_6.setObjectName(u"label_6")
138
135
 
139
- self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label_6)
136
+ self.formLayout.setWidget(0, QFormLayout.ItemRole.LabelRole, self.label_6)
140
137
 
141
138
  self.pointCounter = QDoubleSpinBox(self.mainWidget)
142
139
  self.pointCounter.setObjectName(u"pointCounter")
@@ -156,12 +153,12 @@ class Ui_MoodleTestGenerator(object):
156
153
  self.pointCounter.setDecimals(1)
157
154
  self.pointCounter.setMaximum(999.899999999999977)
158
155
 
159
- self.formLayout.setWidget(0, QFormLayout.FieldRole, self.pointCounter)
156
+ self.formLayout.setWidget(0, QFormLayout.ItemRole.FieldRole, self.pointCounter)
160
157
 
161
158
  self.label_7 = QLabel(self.mainWidget)
162
159
  self.label_7.setObjectName(u"label_7")
163
160
 
164
- self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_7)
161
+ self.formLayout.setWidget(1, QFormLayout.ItemRole.LabelRole, self.label_7)
165
162
 
166
163
  self.questionCounter = QDoubleSpinBox(self.mainWidget)
167
164
  self.questionCounter.setObjectName(u"questionCounter")
@@ -169,19 +166,7 @@ class Ui_MoodleTestGenerator(object):
169
166
  self.questionCounter.setDecimals(0)
170
167
  self.questionCounter.setMaximum(300.000000000000000)
171
168
 
172
- self.formLayout.setWidget(1, QFormLayout.FieldRole, self.questionCounter)
173
-
174
- self.label_8 = QLabel(self.mainWidget)
175
- self.label_8.setObjectName(u"label_8")
176
-
177
- self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_8)
178
-
179
- self.categoriesCounter = QSpinBox(self.mainWidget)
180
- self.categoriesCounter.setObjectName(u"categoriesCounter")
181
- self.categoriesCounter.setFont(font2)
182
- self.categoriesCounter.setMaximum(999)
183
-
184
- self.formLayout.setWidget(2, QFormLayout.FieldRole, self.categoriesCounter)
169
+ self.formLayout.setWidget(1, QFormLayout.ItemRole.FieldRole, self.questionCounter)
185
170
 
186
171
 
187
172
  self.verticalLayout_2.addLayout(self.formLayout)
@@ -232,35 +217,25 @@ class Ui_MoodleTestGenerator(object):
232
217
  self.formLayout_2 = QFormLayout()
233
218
  self.formLayout_2.setObjectName(u"formLayout_2")
234
219
  self.formLayout_2.setContentsMargins(5, 5, 5, 5)
235
- self.label_9 = QLabel(self.mainWidget)
236
- self.label_9.setObjectName(u"label_9")
237
-
238
- self.formLayout_2.setWidget(2, QFormLayout.LabelRole, self.label_9)
239
-
240
- self.checkBoxIncludeCategories = QCheckBox(self.mainWidget)
241
- self.checkBoxIncludeCategories.setObjectName(u"checkBoxIncludeCategories")
220
+ self.label_10 = QLabel(self.mainWidget)
221
+ self.label_10.setObjectName(u"label_10")
242
222
 
243
- self.formLayout_2.setWidget(2, QFormLayout.FieldRole, self.checkBoxIncludeCategories)
223
+ self.formLayout_2.setWidget(0, QFormLayout.ItemRole.LabelRole, self.label_10)
244
224
 
245
225
  self.spinBoxDefaultQVariant = QSpinBox(self.mainWidget)
246
226
  self.spinBoxDefaultQVariant.setObjectName(u"spinBoxDefaultQVariant")
247
227
 
248
- self.formLayout_2.setWidget(1, QFormLayout.FieldRole, self.spinBoxDefaultQVariant)
249
-
250
- self.checkBoxUseDefQVariant = QCheckBox(self.mainWidget)
251
- self.checkBoxUseDefQVariant.setObjectName(u"checkBoxUseDefQVariant")
228
+ self.formLayout_2.setWidget(0, QFormLayout.ItemRole.FieldRole, self.spinBoxDefaultQVariant)
252
229
 
253
- self.formLayout_2.setWidget(0, QFormLayout.FieldRole, self.checkBoxUseDefQVariant)
254
-
255
- self.label_10 = QLabel(self.mainWidget)
256
- self.label_10.setObjectName(u"label_10")
230
+ self.label_9 = QLabel(self.mainWidget)
231
+ self.label_9.setObjectName(u"label_9")
257
232
 
258
- self.formLayout_2.setWidget(1, QFormLayout.LabelRole, self.label_10)
233
+ self.formLayout_2.setWidget(1, QFormLayout.ItemRole.LabelRole, self.label_9)
259
234
 
260
- self.label_11 = QLabel(self.mainWidget)
261
- self.label_11.setObjectName(u"label_11")
235
+ self.checkBoxIncludeCategories = QCheckBox(self.mainWidget)
236
+ self.checkBoxIncludeCategories.setObjectName(u"checkBoxIncludeCategories")
262
237
 
263
- self.formLayout_2.setWidget(0, QFormLayout.LabelRole, self.label_11)
238
+ self.formLayout_2.setWidget(1, QFormLayout.ItemRole.FieldRole, self.checkBoxIncludeCategories)
264
239
 
265
240
 
266
241
  self.verticalLayout_2.addLayout(self.formLayout_2)
@@ -333,14 +308,12 @@ class Ui_MoodleTestGenerator(object):
333
308
  self.menuTools.addAction(self.actionParseAll)
334
309
  self.menuTools.addAction(self.actionPreviewQ)
335
310
  self.menuTools.addAction(self.actionSetting)
336
- self.menuHelp.addAction(self.actionAbout)
337
- self.menuHelp.addAction(self.actionDocumentation)
338
311
  self.toolBar.addAction(self.actionInput_Spreadsheet)
339
312
  self.toolBar.addAction(self.actionParseAll)
340
313
  self.toolBar.addSeparator()
341
314
  self.toolBar_3.addAction(self.actionEquationChecker)
342
315
  self.toolBar_3.addAction(self.actionPreviewQ)
343
- self.toolBar_2.addAction(self.actionDocumentation)
316
+ self.toolBar_2.addAction(self.actionAbout)
344
317
  self.toolBar_2.addAction(self.actionSetting)
345
318
 
346
319
  self.retranslateUi(MoodleTestGenerator)
@@ -368,15 +341,11 @@ class Ui_MoodleTestGenerator(object):
368
341
  self.actionPreviewQ.setShortcut(QCoreApplication.translate("MoodleTestGenerator", u"Ctrl+P", None))
369
342
  #endif // QT_CONFIG(shortcut)
370
343
  self.actionAbout.setText(QCoreApplication.translate("MoodleTestGenerator", u"About", None))
371
- self.actionDocumentation.setText(QCoreApplication.translate("MoodleTestGenerator", u"Documentation", None))
372
- #if QT_CONFIG(shortcut)
373
- self.actionDocumentation.setShortcut(QCoreApplication.translate("MoodleTestGenerator", u"F1", None))
374
- #endif // QT_CONFIG(shortcut)
375
344
  self.actionSetting.setText(QCoreApplication.translate("MoodleTestGenerator", u"Settings", None))
376
345
  self.checkBoxQuestionListSelectAll.setText(QCoreApplication.translate("MoodleTestGenerator", u"Select all", None))
377
346
  self.label.setText(QCoreApplication.translate("MoodleTestGenerator", u"Question List", None))
378
347
  ___qtreewidgetitem = self.treeWidget.headerItem()
379
- ___qtreewidgetitem.setText(3, QCoreApplication.translate("MoodleTestGenerator", u"Variant", None));
348
+ ___qtreewidgetitem.setText(3, QCoreApplication.translate("MoodleTestGenerator", u"Variants", None));
380
349
  ___qtreewidgetitem.setText(2, QCoreApplication.translate("MoodleTestGenerator", u"Points", None));
381
350
  ___qtreewidgetitem.setText(1, QCoreApplication.translate("MoodleTestGenerator", u"Description", None));
382
351
  ___qtreewidgetitem.setText(0, QCoreApplication.translate("MoodleTestGenerator", u"Question ID", None));
@@ -385,23 +354,15 @@ class Ui_MoodleTestGenerator(object):
385
354
  self.pointCounter.setPrefix("")
386
355
  self.label_7.setText(QCoreApplication.translate("MoodleTestGenerator", u"Questions", None))
387
356
  self.questionCounter.setPrefix("")
388
- self.label_8.setText(QCoreApplication.translate("MoodleTestGenerator", u"Categories", None))
389
- self.categoriesCounter.setSuffix("")
390
- self.categoriesCounter.setPrefix("")
391
357
  self.label_2.setText(QCoreApplication.translate("MoodleTestGenerator", u"Input", None))
392
358
  self.buttonSpreadSheet.setText(QCoreApplication.translate("MoodleTestGenerator", u"Select spreadsheet", None))
393
359
  self.label_3.setText(QCoreApplication.translate("MoodleTestGenerator", u"Output", None))
360
+ self.label_10.setText(QCoreApplication.translate("MoodleTestGenerator", u"Default Question Variant", None))
394
361
  #if QT_CONFIG(tooltip)
395
362
  self.label_9.setToolTip(QCoreApplication.translate("MoodleTestGenerator", u"If enabled, all questions will be categorized, when importing into moodle. Otherwise they will all be imported into one category", None))
396
363
  #endif // QT_CONFIG(tooltip)
397
364
  self.label_9.setText(QCoreApplication.translate("MoodleTestGenerator", u"Include Questions in Categories", None))
398
365
  self.checkBoxIncludeCategories.setText("")
399
- self.checkBoxUseDefQVariant.setText("")
400
- self.label_10.setText(QCoreApplication.translate("MoodleTestGenerator", u"Default Question Variant", None))
401
- #if QT_CONFIG(tooltip)
402
- self.label_11.setToolTip(QCoreApplication.translate("MoodleTestGenerator", u"If enabled it will always use the question variant that is set below. If not, it will ask everytime, which question Variant should be used", None))
403
- #endif // QT_CONFIG(tooltip)
404
- self.label_11.setText(QCoreApplication.translate("MoodleTestGenerator", u"Use default question Variant", None))
405
366
  self.buttonTestGen.setText(QCoreApplication.translate("MoodleTestGenerator", u"export selected Questions to examfile", None))
406
367
  self.label_4.setText(QCoreApplication.translate("MoodleTestGenerator", u"Logger", None))
407
368
  self.menuFile.setTitle(QCoreApplication.translate("MoodleTestGenerator", u"File", None))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: excel2moodle
3
- Version: 0.3.3
3
+ Version: 0.3.5
4
4
  Summary: A package for converting questions from a spreadsheet, to valid moodle-xml
5
5
  Author: Jakob Bosse
6
6
  License-Expression: GPL-3.0-or-later
@@ -15,8 +15,9 @@ License-File: LICENSE
15
15
  Requires-Dist: pyside6>=6.8.0
16
16
  Requires-Dist: pandas>=2.1.3
17
17
  Requires-Dist: openpyxl>=3.1.5
18
- Requires-Dist: asteval
19
- Requires-Dist: odfpy
18
+ Requires-Dist: lxml>=5.4.0
19
+ Requires-Dist: odfpy>=1.4.1
20
+ Requires-Dist: asteval>=1.0.6
20
21
  Dynamic: license-file
21
22
 
22
23
  # excel 2 Moodle
@@ -0,0 +1,33 @@
1
+ excel2moodle/__init__.py,sha256=b5hZTSd7Ffy89ct8mGHQbplbqcylrLx3u2h__tyvhs0,2324
2
+ excel2moodle/__main__.py,sha256=8o3KK_RDgyTNW05cRL_iiu7BBHbIqWX9H878eHvf9Ag,544
3
+ excel2moodle/logger.py,sha256=Af4IuJ4bJUCGSNoABakgUzVrYLAD3n9YTQXEXHk4j5Q,3138
4
+ excel2moodle/core/__init__.py,sha256=H4Bt6u076RKb6BH5F58nHLQvYPDUoayosM_Onyr9yT0,398
5
+ excel2moodle/core/category.py,sha256=VunNsfRUv7O8L3XMe1BB2EFxtfCAJFaRafRYRKF15kE,3006
6
+ excel2moodle/core/dataStructure.py,sha256=1lZtV2CULCDbzmfgaFO_l4Jn0OJ6vYJ3hDN2oe81nfE,6215
7
+ excel2moodle/core/etHelpers.py,sha256=i8DAx7YBxrQqzbXFsU-pIvYMPHSRhYci-JvuzY1MzeI,2299
8
+ excel2moodle/core/exceptions.py,sha256=VgbxrnoR9RRnmDYK2rbB_Bv00r7NLWET6FgddPwo3uw,748
9
+ excel2moodle/core/globals.py,sha256=OGBxkgD19etaMP6sTtsTZ_u8NXbnHYdCQYAu9E3pcgE,3692
10
+ excel2moodle/core/numericMultiQ.py,sha256=vr-gYogu2sf2a_Bhvhnu1ZSZFZXM32MfhJesjTkoOQM,2618
11
+ excel2moodle/core/parser.py,sha256=jsBMjluc5OICCkrtT4WNVwO26-MaBOTuiOUbQhN2d6g,15232
12
+ excel2moodle/core/question.py,sha256=ZubBhS3n7wRFgtcKZ4AoUBSsxLyIM1wsmzsBqbSab-I,6489
13
+ excel2moodle/core/questionValidator.py,sha256=a12bPd6hdE5vuj8aoXA0qXVZ0pI98X-uUBzF0oIbzYk,4810
14
+ excel2moodle/core/questionWriter.py,sha256=UiWbrtNSiQiYY_x3sF3nz6Ic0b_lL0uWHyeDNDtFvPM,10985
15
+ excel2moodle/core/stringHelpers.py,sha256=XZAyXKZcQT_bAQSb9tBQs5tMC5soJf_ZhYFHrDX9ck4,2994
16
+ excel2moodle/extra/__init__.py,sha256=PM-id60HD21A3IcGC_fCYFihS8osBGZMIJCcN-ZRsIM,293
17
+ excel2moodle/extra/equationVerification.py,sha256=GLJl1r90d8AAiNy0H2hooZrg3D6aEwNfifYKAe3aGxM,3921
18
+ excel2moodle/ui/__init__.py,sha256=4EdGtpzwH3rgw4xW9E5x9kdPQYwKbo9rehHRZTNxCrQ,44
19
+ excel2moodle/ui/appUi.py,sha256=axZ-DtP2ugz68CPWtqVKU81i5Wq8yG1df3tw3YatDvU,9991
20
+ excel2moodle/ui/dialogs.py,sha256=EgAKcydF4clyEweocjmtyCdsQJdQmvY-LVzOlu_cl_8,5320
21
+ excel2moodle/ui/questionPreviewDialog.py,sha256=_rJvz1GM90aNnj3P6SugEezK7JW6m74ZALgkChohWLM,4980
22
+ excel2moodle/ui/settings.py,sha256=pzYkMz1fBNW2t_H1KRBtcAqMxRbirj4aUY9yK5kuqIY,4288
23
+ excel2moodle/ui/treewidget.py,sha256=mTRqmZHMZT3QTTvt5Gw9L-yl4KdhhulkF7O1KBwW-_E,2449
24
+ excel2moodle/ui/variantDialog.py,sha256=snVaF3_YAc7NWjMRg7NzbjL_PzNbOpt4eiqElkE46io,5414
25
+ excel2moodle/ui/windowDoc.py,sha256=IciZpwrLnGzIQV1aCdKQBg6km3oufHGs8havTFzNJyU,1055
26
+ excel2moodle/ui/windowEquationChecker.py,sha256=fLyal3sbJwpthWCAxLB5vbSFOX23JoivoYksNp3mZVY,7925
27
+ excel2moodle/ui/windowMain.py,sha256=FsaApCyWgngnWPb46R8_01z8q4XeWxRFVqewSIt742c,19027
28
+ excel2moodle-0.3.5.dist-info/licenses/LICENSE,sha256=ywQqe6Sitymkf2lV2NRcx_aGsaC-KbSl_EfEsRXmNRw,35135
29
+ excel2moodle-0.3.5.dist-info/METADATA,sha256=MstfP8n_sfCdP2buwc8lmgX3C4cO9JzReftV-JMehJU,2945
30
+ excel2moodle-0.3.5.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
31
+ excel2moodle-0.3.5.dist-info/entry_points.txt,sha256=myfMLDThuGgWHMJDPPfILiZqo_7D3fhmDdJGqWOAjPw,60
32
+ excel2moodle-0.3.5.dist-info/top_level.txt,sha256=5V1xRUQ9o7UmOCmNoWCZPAuy5nXp3Qbzyqch8fUGT_c,13
33
+ excel2moodle-0.3.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.0)
2
+ Generator: setuptools (80.4.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ excel2moodle = excel2moodle.__main__:main
@@ -1,31 +0,0 @@
1
- excel2moodle/__init__.py,sha256=dsK3KrorPt06FUp18_dw2m4p9P8E7rFf9I0BR-4I28k,4263
2
- excel2moodle/__main__.py,sha256=SsulFcOSlRBF2tLTUIdFgB0EJdSLGBIQ_HO53S4Sih8,541
3
- excel2moodle/core/__init__.py,sha256=E7smxf7ESHlucvho4Gb5oaTHA7IsOv9J-UDIsoKwp84,399
4
- excel2moodle/core/category.py,sha256=rZsQW5-Ud182xCrS4R8B0vrPMrI-azwtfzlTdy89SR4,2982
5
- excel2moodle/core/dataStructure.py,sha256=h82r4wO2PhhHA4EqROjfkqWGUpg6UKQhkyrdjdisLxg,6343
6
- excel2moodle/core/etHelpers.py,sha256=_fd-fGMVNWt1l8FY7xcA2uXOBahxtq8ggYxRYm4SwdA,2354
7
- excel2moodle/core/exceptions.py,sha256=3OLVHMCBgETiOxSsirlsCPvlMN5UgEQcMkRDkCfrUs4,675
8
- excel2moodle/core/globals.py,sha256=9V9-KBSsHMdsRZWg2wGrvjAd6dc3XZG4pNPnun0AHGE,3595
9
- excel2moodle/core/numericMultiQ.py,sha256=InBrn-tsCCYwDb78sGR3FyFxVeN0GfIg63JGtr_tqg4,2751
10
- excel2moodle/core/parser.py,sha256=0bLP_bkTFu3URw08sn1zJCvA3YCKxDAC4a6I14koHho,13408
11
- excel2moodle/core/question.py,sha256=zzdL_7BdWs0wUVl8-06gLkKu0Is3n0zU-2ZkaYhU504,5913
12
- excel2moodle/core/questionValidator.py,sha256=taOrrR6pd5mN7SGpET9eLOvb1v5NWvg_VgMj8opQlZ4,4791
13
- excel2moodle/core/questionWriter.py,sha256=kyUTrnjWrLEWdez5_7FPNJ0Cs_fF5d16oOQiVvHv3zA,10242
14
- excel2moodle/core/stringHelpers.py,sha256=9BqR7yx2bL8WknVMPuNlmWz05bgi4qWjFYHsgaftpZw,3141
15
- excel2moodle/extra/__init__.py,sha256=e70OmuW3j7N4ErIIHlK4vkmCKcpRbitJCdJvzjego8c,339
16
- excel2moodle/extra/equationVerification.py,sha256=FOvVBQZ357fbA5nYkHjvvWWVP3pQpo4RK3H7vru9v3A,4278
17
- excel2moodle/ui/__init__.py,sha256=4EdGtpzwH3rgw4xW9E5x9kdPQYwKbo9rehHRZTNxCrQ,44
18
- excel2moodle/ui/appUi.py,sha256=TEqslEDExDOyYwCh7czg3YZggPdZewFiImbpzACLYLU,10533
19
- excel2moodle/ui/dialogs.py,sha256=5dnzRN9cwaxjJsxA7I9v1imH4k6XVzzievYi3PR32XI,3038
20
- excel2moodle/ui/questionPreviewDialog.py,sha256=_rJvz1GM90aNnj3P6SugEezK7JW6m74ZALgkChohWLM,4980
21
- excel2moodle/ui/settings.py,sha256=PB0uBMCd8DIRSFfvUAPs5hK4UEcb0y7dG9ZJ--kOvuQ,1115
22
- excel2moodle/ui/treewidget.py,sha256=xiYWhJeJ9o9Iubtr44HcyJas9v4m8aBsHNdokQAHi80,2357
23
- excel2moodle/ui/variantDialog.py,sha256=snVaF3_YAc7NWjMRg7NzbjL_PzNbOpt4eiqElkE46io,5414
24
- excel2moodle/ui/windowDoc.py,sha256=IciZpwrLnGzIQV1aCdKQBg6km3oufHGs8havTFzNJyU,1055
25
- excel2moodle/ui/windowEquationChecker.py,sha256=fLyal3sbJwpthWCAxLB5vbSFOX23JoivoYksNp3mZVY,7925
26
- excel2moodle/ui/windowMain.py,sha256=sB1ahkAwxFxO3EYP3X_MuB6ohgXwK5NUQHWeFo4eqrI,21062
27
- excel2moodle-0.3.3.dist-info/licenses/LICENSE,sha256=ywQqe6Sitymkf2lV2NRcx_aGsaC-KbSl_EfEsRXmNRw,35135
28
- excel2moodle-0.3.3.dist-info/METADATA,sha256=i7lC9k3j8ErKfWNnPAngdrnDAWIqC5V6egSB5uWivW8,2904
29
- excel2moodle-0.3.3.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
30
- excel2moodle-0.3.3.dist-info/top_level.txt,sha256=5V1xRUQ9o7UmOCmNoWCZPAuy5nXp3Qbzyqch8fUGT_c,13
31
- excel2moodle-0.3.3.dist-info/RECORD,,