]> Softwares of Agnibho - medscript.git/blob - setting.py
Bugfix: crash on opening config and preset editors
[medscript.git] / setting.py
1 # MedScript
2 # Copyright (C) 2023 Dr. Agnibho Mondal
3 # This file is part of MedScript.
4 # MedScript is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5 # MedScript is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6 # You should have received a copy of the GNU General Public License along with MedScript. If not, see <https://www.gnu.org/licenses/>.
7
8 from PyQt6.QtWidgets import QDialog, QFormLayout, QHBoxLayout, QVBoxLayout, QPushButton, QLabel, QLineEdit, QTextEdit, QComboBox, QCheckBox, QMessageBox, QFileDialog, QListWidget
9 from PyQt6.QtGui import QIcon
10 from PyQt6.QtCore import Qt, pyqtSignal
11 from glob import glob
12 import logging, os, json
13 from prescription import Prescriber
14 from config import config, config_file
15
16 class EditConfiguration(QDialog):
17
18 def select_directory(self):
19 d=QFileDialog.getExistingDirectory(self, "Select Directory", config["data_directory"])
20 if(d):
21 self.input_directory.setText(d)
22 def select_prescriber(self):
23 f=QFileDialog.getOpenFileName(self, "Select Prescriber", config["prescriber_directory"], "JSON (*.json);; All Files (*)")[0]
24 if(f):
25 self.input_prescriber.setText(f)
26 def select_key(self):
27 f=QFileDialog.getOpenFileName(self, "Select Private Key", os.path.expanduser("~"), "PEM (*.pem);; All Files (*)")[0]
28 if(f):
29 self.input_key.setText(f)
30 def select_certificate(self):
31 f=QFileDialog.getOpenFileName(self, "Select Certificate", os.path.expanduser("~"), "PEM (*.pem);; All Files (*)")[0]
32 if(f):
33 self.input_certificate.setText(f)
34 def select_root(self):
35 f=QFileDialog.getOpenFileName(self, "Select Root Bundle", os.path.expanduser("~"), "PEM (*.pem);; All Files (*)")[0]
36 if(f):
37 self.input_root.setText(f)
38
39 def load(self):
40 try:
41 self.input_directory.setText(self.config["data_directory"])
42 self.input_prescriber.setText(self.config["prescriber"])
43 self.input_newline.setChecked(bool(self.config["preset_newline"]))
44 self.input_delimiter.setCurrentText(self.config["preset_delimiter"])
45 self.input_agedob.setChecked(bool(self.config["age_default"]))
46 self.input_markdown.setChecked(bool(self.config["markdown"]))
47 self.input_update.setChecked(bool(self.config["check_update"]))
48 self.input_form.setChecked(bool(self.config["enable_form"]))
49 self.input_plugin.setChecked(bool(self.config["enable_plugin"]))
50 self.input_smime.setChecked(bool(self.config["smime"]))
51 self.input_key.setText(self.config["private_key"])
52 self.input_certificate.setText(self.config["certificate"])
53 self.input_root.setText(self.config["root_bundle"])
54 except Exception as e:
55 QMessageBox.critical(self,"Failed to load", "Failed to load the data into the application.")
56 logging.exception(e)
57
58 def save(self):
59 if(QMessageBox.StandardButton.Yes==QMessageBox.question(self,"Confirm Save", "This action will overwrite the previous configuration. Continue?")):
60 try:
61 self.config["data_directory"]=self.input_directory.text()
62 self.config["prescriber"]=self.input_prescriber.text()
63 self.config["preset_newline"]=self.input_newline.isChecked()
64 self.config["preset_delimiter"]=self.input_delimiter.currentText()
65 self.config["age_default"]=self.input_agedob.isChecked()
66 self.config["markdown"]=self.input_markdown.isChecked()
67 self.config["check_update"]=self.input_update.isChecked()
68 self.config["enable_form"]=self.input_form.isChecked()
69 self.config["enable_plugin"]=self.input_plugin.isChecked()
70 self.config["smime"]=self.input_smime.isChecked()
71 self.config["private_key"]=self.input_key.text()
72 self.config["certificate"]=self.input_certificate.text()
73 self.config["root_bundle"]=self.input_root.text()
74 with open(config_file, "w") as f:
75 f.write(json.dumps(self.config, indent=4))
76 QMessageBox.information(self,"Saved", "Configuration saved. Please restart MedScript.")
77 self.close()
78 except Exception as e:
79 QMessageBox.critical(self,"Failed to save", "Failed to save the data to the file.")
80 logging.exception(e)
81
82 def __init__(self, *args, **kwargs):
83 super().__init__(*args, **kwargs)
84
85 try:
86 with open(config_file) as f:
87 self.config=json.loads(f.read()) | config
88 except Exception as e:
89 logging.exception(e)
90 self.config=config
91
92 self.setWindowTitle("Configuration Editor")
93
94 layout=QFormLayout(self)
95 self.input_directory=QLineEdit(self)
96 btn_directory=QPushButton("Select Directory", self)
97 btn_directory.clicked.connect(self.select_directory)
98 layout_directory=QHBoxLayout()
99 layout_directory.addWidget(self.input_directory)
100 layout_directory.addWidget(btn_directory)
101 layout.addRow("Data Directory", layout_directory)
102 self.input_prescriber=QLineEdit(self)
103 btn_prescriber=QPushButton("Select File", self)
104 btn_prescriber.clicked.connect(self.select_prescriber)
105 layout_prescriber=QHBoxLayout()
106 layout_prescriber.addWidget(self.input_prescriber)
107 layout_prescriber.addWidget(btn_prescriber)
108 layout.addRow("Prescriber", layout_prescriber)
109 self.input_newline=QCheckBox("Add newline after preset", self)
110 layout.addRow("Preset Newline", self.input_newline)
111 self.input_delimiter=QComboBox(self)
112 self.input_delimiter.addItems([",", ";"])
113 layout.addRow("Preset Delimiter", self.input_delimiter)
114 self.input_agedob=QCheckBox("Age default in new prescriptions", self)
115 layout.addRow("Age/DOB", self.input_agedob)
116 self.input_markdown=QCheckBox("Enable markdown formatting", self)
117 layout.addRow("Markdown", self.input_markdown)
118 self.input_update=QCheckBox("Check update on startup", self)
119 layout.addRow("Check Update", self.input_update)
120 self.input_form=QCheckBox("Enable custom input form", self)
121 layout.addRow("Form", self.input_form)
122 self.input_plugin=QCheckBox("Enable plugin", self)
123 layout.addRow("Plugin", self.input_plugin)
124 self.input_smime=QCheckBox("Enable digital signature (experimental)", self)
125 layout.addRow("S/MIME", self.input_smime)
126 self.input_key=QLineEdit(self)
127 btn_key=QPushButton("Select File", self)
128 btn_key.clicked.connect(self.select_key)
129 layout_key=QHBoxLayout()
130 layout_key.addWidget(self.input_key)
131 layout_key.addWidget(btn_key)
132 layout.addRow("Private Key", layout_key)
133 self.input_certificate=QLineEdit(self)
134 btn_certificate=QPushButton("Select File", self)
135 btn_certificate.clicked.connect(self.select_certificate)
136 layout_certificate=QHBoxLayout()
137 layout_certificate.addWidget(self.input_certificate)
138 layout_certificate.addWidget(btn_certificate)
139 layout.addRow("X509 Certificate", layout_certificate)
140 self.input_root=QLineEdit(self)
141 btn_root=QPushButton("Select File", self)
142 btn_root.clicked.connect(self.select_root)
143 layout_root=QHBoxLayout()
144 layout_root.addWidget(self.input_root)
145 layout_root.addWidget(btn_root)
146 layout.addRow("Root Bundle", layout_root)
147 button_save=QPushButton("Save")
148 button_save.clicked.connect(self.save)
149 button_reset=QPushButton("Reset")
150 button_reset.clicked.connect(self.load)
151 layout_btn=QHBoxLayout()
152 layout_btn.addWidget(button_save)
153 layout_btn.addWidget(button_reset)
154 layout.addRow("", layout_btn)
155
156 self.setWindowIcon(QIcon(os.path.join("resource", "icon_medscript.ico")))
157
158 self.load()
159
160 class EditPrescriber(QDialog):
161
162 signal_save=pyqtSignal(str)
163
164 file=""
165 prescriber=""
166
167 def load(self, file=None):
168 try:
169 if(file):
170 self.file=file
171 else:
172 self.file=config["prescriber"]
173 with open(self.file) as data:
174 self.prescriber=json.loads(data.read())
175 self.input_name.setText(self.prescriber["name"])
176 self.input_qualification.setText(self.prescriber["qualification"])
177 self.input_registration.setText(self.prescriber["registration"])
178 self.input_address.setText(self.prescriber["address"])
179 self.input_contact.setText(self.prescriber["contact"])
180 self.input_extra.setText(self.prescriber["extra"])
181 except Exception as e:
182 QMessageBox.critical(self,"Failed to load", "Failed to load the data into the application.")
183 logging.error(e)
184
185 def save(self, file=False):
186 if(file is not False or QMessageBox.StandardButton.Yes==QMessageBox.question(self,"Confirm Save", "This action will overwrite the previous information. Continue?")):
187 if file is False:
188 file=self.file
189 try:
190 self.prescriber["name"]=self.input_name.text()
191 self.prescriber["qualification"]=self.input_qualification.text()
192 self.prescriber["registration"]=self.input_registration.text()
193 self.prescriber["address"]=self.input_address.toPlainText()
194 self.prescriber["contact"]=self.input_contact.text()
195 self.prescriber["extra"]=self.input_extra.toPlainText()
196 with open(file, "w") as f:
197 f.write(json.dumps(self.prescriber, indent=4))
198 QMessageBox.information(self,"Saved", "Information saved.")
199 self.signal_save.emit(self.file)
200 self.close()
201 except Exception as e:
202 QMessageBox.critical(self,"Failed to save", "Failed to save the data to the file.")
203 logging.error(e)
204
205 def __init__(self, *args, **kwargs):
206 super().__init__(*args, **kwargs)
207
208 self.setWindowTitle("Prescriber Editor")
209
210 layout=QFormLayout(self)
211 self.input_name=QLineEdit(self)
212 layout.addRow("Name", self.input_name)
213 self.input_qualification=QLineEdit(self)
214 layout.addRow("Qualification", self.input_qualification)
215 self.input_registration=QLineEdit(self)
216 layout.addRow("Registration", self.input_registration)
217 self.input_address=QTextEdit(self)
218 layout.addRow("Adress", self.input_address)
219 self.input_contact=QLineEdit(self)
220 layout.addRow("Contact", self.input_contact)
221 self.input_extra=QTextEdit(self)
222 layout.addRow("Extra", self.input_extra)
223 button_save=QPushButton("Save")
224 button_save.clicked.connect(self.save)
225 layout.addRow("", button_save)
226
227 self.setWindowIcon(QIcon(os.path.join("resource", "icon_medscript.ico")))
228
229 self.load()
230
231 class SelectPrescriber(QDialog):
232
233 signal_select=pyqtSignal(str)
234 signal_edit=pyqtSignal(str)
235
236 listAll={"obj": [], "name": [], "file": []}
237
238 def load(self):
239 self.listAll={"obj": [], "name": [], "file": []}
240 self.showAll.clear()
241 for i in glob(os.path.join(config["prescriber_directory"], "*.json")):
242 self.listAll["obj"].append(Prescriber(i))
243 try:
244 self.listAll["name"].append(self.listAll["obj"][-1].name)
245 except AttributeError:
246 del self.listAll["obj"][-1]
247 self.listAll["file"].append(i)
248 for i in self.listAll["name"]:
249 self.showAll.addItem(i)
250
251 def select(self):
252 txt=self.showAll.currentItem().text()
253 idx=self.listAll["name"].index(txt)
254 self.signal_select.emit(self.listAll["file"][idx])
255 self.close()
256
257 def new(self):
258 num=1
259 file=os.path.join(config["prescriber_directory"], "prescriber"+str(num)+".json")
260 while(os.path.exists(file)):
261 num=num+1
262 file=os.path.join(config["prescriber_directory"], "prescriber"+str(num)+".json")
263 self.signal_edit.emit(file)
264 self.close()
265
266 def edit(self):
267 txt=self.showAll.currentItem().text()
268 idx=self.listAll["name"].index(txt)
269 self.signal_edit.emit(self.listAll["file"][idx])
270 self.close()
271
272 def delete(self):
273 txt=self.showAll.currentItem().text()
274 idx=self.listAll["name"].index(txt)
275 file=self.listAll["file"][idx]
276 if(file==config["prescriber"]):
277 QMessageBox.warning(self,"Unable to Delete", "Default prescriber file cannot be deleted.")
278 else:
279 if(QMessageBox.StandardButton.Yes==QMessageBox.question(self,"Confirm Delete", "Are you sure you want to delete the prescriber? This action cannot be undone.")):
280 os.unlink(self.listAll["file"][idx])
281 self.showAll.takeItem(self.showAll.currentRow())
282
283 def __init__(self, *args, **kwargs):
284 super().__init__(*args, **kwargs)
285
286 self.setWindowTitle("Prescriber Selector")
287
288 layout=QVBoxLayout(self)
289 self.showAll=QListWidget()
290 self.showAll.doubleClicked.connect(self.select)
291 layout.addWidget(self.showAll)
292 layout2=QHBoxLayout()
293 btn_select=QPushButton("Select")
294 btn_select.clicked.connect(self.select)
295 layout2.addWidget(btn_select)
296 btn_new=QPushButton("New")
297 btn_new.clicked.connect(self.new)
298 layout2.addWidget(btn_new)
299 btn_edit=QPushButton("Edit")
300 btn_edit.clicked.connect(self.edit)
301 layout2.addWidget(btn_edit)
302 btn_del=QPushButton("Delete")
303 btn_del.clicked.connect(self.delete)
304 layout2.addWidget(btn_del)
305 layout.addLayout(layout2)
306
307 self.setWindowIcon(QIcon(os.path.join("resource", "icon_medscript.ico")))
308
309 self.load()