From 1959a9ae54d2cae438194e166d9e600e0e83a8d5 Mon Sep 17 00:00:00 2001 From: Agnibho Mondal Date: Mon, 6 Nov 2023 22:47:12 +0530 Subject: [PATCH] Implemented custom input form --- config.py | 4 +++ customform.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ prescription.py | 8 +++-- setting.py | 4 +++ window.py | 17 ++++++++-- 5 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 customform.py diff --git a/config.py b/config.py index 61adb5d..48d37a8 100644 --- a/config.py +++ b/config.py @@ -33,6 +33,8 @@ default = { "template_directory": "template", "template": "default_prescription", "preset_directory": "preset", + "form_directory": "form", + "enable_form": False, "plugin_directory": "plugin", "enable_plugin": False, "preset_newline": True, @@ -57,6 +59,7 @@ config["filename"]=args.filename config["data_directory"]=os.path.abspath(os.path.join(real_dir, os.path.expanduser(config["data_directory"]))) config["document_directory"]=os.path.join(config["data_directory"], config["document_directory"]) config["preset_directory"]=os.path.join(config["data_directory"], config["preset_directory"]) +config["form_directory"]=os.path.join(config["data_directory"], config["form_directory"]) config["plugin_directory"]=os.path.join(config["data_directory"], config["plugin_directory"]) config["template_directory"]=os.path.join(config["data_directory"], config["template_directory"]) config["template"]=os.path.join(config["template_directory"], config["template"]) @@ -78,6 +81,7 @@ os.makedirs(config["data_directory"], exist_ok=True) os.makedirs(config["document_directory"], exist_ok=True) os.makedirs(config["prescriber_directory"], exist_ok=True) os.makedirs(config["preset_directory"], exist_ok=True) +os.makedirs(config["form_directory"], exist_ok=True) os.makedirs(config["plugin_directory"], exist_ok=True) os.makedirs(config["template_directory"], exist_ok=True) if not os.path.exists(os.path.join(config["data_directory"], "config.json")): diff --git a/customform.py b/customform.py new file mode 100644 index 0000000..d58bfd9 --- /dev/null +++ b/customform.py @@ -0,0 +1,88 @@ +# MedScript +# Copyright (C) 2023 Dr. Agnibho Mondal +# This file is part of MedScript. +# 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. +# 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. +# You should have received a copy of the GNU General Public License along with MedScript. If not, see . + +from PyQt6.QtWidgets import QWidget, QFormLayout, QLineEdit, QTextEdit, QCheckBox, QDateTimeEdit, QCalendarWidget +from PyQt6.QtCore import QDateTime +from glob import glob +import os, json, sys, dateutil.parser +from config import config + +class CustomForm(QWidget): + + forms=[] + custom=[] + inputs=[] + + def load(self): + for i in glob(os.path.join(config["form_directory"], "*")): + with open(i) as f: + try: + self.forms.append(json.loads(f.read())) + except Exception as e: + print(e) + for i in self.forms: + try: + for j in i["form"]: + self.custom.append({j["name"]: ""}) + if("type" in j and j["type"]=="text"): + self.inputs.append([j["description"], QTextEdit()]) + elif("type" in j and j["type"]=="date"): + d=QDateTimeEdit() + d.setDisplayFormat("MMMM dd, yyyy hh:mm a") + d.setCalendarPopup(True) + d.setCalendarWidget(QCalendarWidget()) + self.inputs.append([j["description"], d]) + elif("type" in j and j["type"]=="check"): + self.inputs.append([j["description"], QCheckBox()]) + else: + self.inputs.append([j["description"], QLineEdit()]) + except Exception as e: + raise(e) + + def getData(self): + try: + for index, item in enumerate(self.custom): + if(isinstance(self.inputs[index][1], QLineEdit)): + self.custom[index][list(item)[0]]=self.inputs[index][1].text() + elif(isinstance(self.inputs[index][1], QTextEdit)): + self.custom[index][list(item)[0]]=self.inputs[index][1].toPlainText() + elif(isinstance(self.inputs[index][1], QCheckBox)): + self.custom[index][list(item)[0]]=self.inputs[index][1].isChecked() + elif(isinstance(self.inputs[index][1], QDateTimeEdit)): + self.custom[index][list(item)[0]]=self.inputs[index][1].text() + except Exception as e: + print(e) + return(self.custom) + + def setData(self, custom=False): + try: + if(custom): + self.custom=custom + for index, item in enumerate(self.custom): + if(isinstance(self.inputs[index][1], QLineEdit)): + self.inputs[index][1].setText(self.custom[index][list(item)[0]]) + elif(isinstance(self.inputs[index][1], QTextEdit)): + self.inputs[index][1].setText(self.custom[index][list(item)[0]]) + elif(isinstance(self.inputs[index][1], QCheckBox)): + self.inputs[index][1].setChecked(bool(self.custom[index][list(item)[0]])) + elif(isinstance(self.inputs[index][1], QDateTimeEdit)): + pdate=dateutil.parser.parse(self.custom[index][list(item)[0]]) + d=QDateTime.fromString(pdate.strftime("%Y-%m-%d %H:%M:%S"), "yyyy-MM-dd hh:mm:ss") + self.inputs[index][1].setDateTime(d) + except Exception as e: + print(e) + + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + if(config["enable_form"]): + self.load() + + layout=QFormLayout(self) + for i in self.inputs: + layout.addRow(i[0], i[1]) diff --git a/prescription.py b/prescription.py index 3a2c901..ecfaf8c 100644 --- a/prescription.py +++ b/prescription.py @@ -39,14 +39,14 @@ class Prescription: file="" - def __init__(self, date="", id="", name="", dob="", age="", sex="", address="", contact="", extra="", mode="", daw="", diagnosis="", note="", report="", advice="", investigation="", medication="", additional="", certificate="", prescriber=None): - self.set_data(date, name, dob, age, sex, address, contact, extra, mode, daw, diagnosis, note, report, advice, investigation, medication, additional, certificate) + def __init__(self, date="", id="", name="", dob="", age="", sex="", address="", contact="", extra="", mode="", daw="", diagnosis="", note="", report="", advice="", investigation="", medication="", additional="", certificate="", custom=None, prescriber=None): + self.set_data(date, name, dob, age, sex, address, contact, extra, mode, daw, diagnosis, note, report, advice, investigation, medication, additional, certificate, custom) if prescriber is None: self.prescriber = Prescriber() else: self.prescriber = prescriber - def set_data(self, date="", id="", name="", dob="", age="", sex="", address="", contact="", extra="", mode="", daw="", diagnosis="", note="", report="", advice="", investigation="", medication="", additional="", certificate=""): + def set_data(self, date="", id="", name="", dob="", age="", sex="", address="", contact="", extra="", mode="", daw="", diagnosis="", note="", report="", advice="", investigation="", medication="", additional="", certificate="", custom=None): self.date = date self.id = id self.name = name @@ -70,6 +70,7 @@ class Prescription: self.medication = medication self.additional = additional self.certificate = certificate + self.custom = custom def set_data_from_json(self, data): self.prescriber.set_data_from_json(data.get("prescriber")) @@ -92,6 +93,7 @@ class Prescription: self.medication = data.get("medication") self.additional = data.get("additional") self.certificate = data.get("certificate") + self.custom = data.get("custom") def get_json(self): return(json.dumps(self, default=lambda o: o.__dict__, indent=4)) diff --git a/setting.py b/setting.py index 7092248..a3471e4 100644 --- a/setting.py +++ b/setting.py @@ -42,6 +42,7 @@ class EditConfiguration(QDialog): self.input_delimiter.setCurrentText(self.config["preset_delimiter"]) self.input_markdown.setChecked(bool(self.config["markdown"])) self.input_update.setChecked(bool(self.config["check_update"])) + self.input_form.setChecked(bool(self.config["enable_form"])) self.input_plugin.setChecked(bool(self.config["enable_plugin"])) self.input_smime.setChecked(bool(self.config["smime"])) self.input_key.setText(self.config["private_key"]) @@ -60,6 +61,7 @@ class EditConfiguration(QDialog): self.config["preset_delimiter"]=self.input_delimiter.currentText() self.config["markdown"]=self.input_markdown.isChecked() self.config["check_update"]=self.input_update.isChecked() + self.config["enable_form"]=self.input_form.isChecked() self.config["enable_plugin"]=self.input_plugin.isChecked() self.config["smime"]=self.input_smime.isChecked() self.config["private_key"]=self.input_key.text() @@ -109,6 +111,8 @@ class EditConfiguration(QDialog): layout.addRow("Markdown", self.input_markdown) self.input_update=QCheckBox("Check update on startup", self) layout.addRow("Check Update", self.input_update) + self.input_form=QCheckBox("Enable custom input form", self) + layout.addRow("Form", self.input_form) self.input_plugin=QCheckBox("Enable plugin", self) layout.addRow("Plugin", self.input_plugin) self.input_smime=QCheckBox("Enable digital signature (experimental)", self) diff --git a/window.py b/window.py index 692af25..c423ee7 100644 --- a/window.py +++ b/window.py @@ -26,6 +26,7 @@ from viewbox import ViewBox from preset import Preset from tabular import Tabular from index import Index +from customform import CustomForm from plugin import Plugin class MainWindow(QMainWindow): @@ -327,7 +328,7 @@ class MainWindow(QMainWindow): if config["preset_newline"]: self.input_certificate.insertPlainText("\n") - def load_interface(self, file="", date=None, id="", name="", dob="", age="", sex="", address="", contact="", extra="", mode="", daw="", diagnosis="", note="", report="", advice="", investigation="", medication="", additional="", certificate=""): + def load_interface(self, file="", date=None, id="", name="", dob="", age="", sex="", address="", contact="", extra="", mode="", daw="", diagnosis="", note="", report="", advice="", investigation="", medication="", additional="", certificate="", custom=None): try: file_msg=self.current_file.file if self.current_file.file else "New file" sign_msg="(signed)" if config["smime"] and self.current_file.is_signed() else "" @@ -369,6 +370,7 @@ class MainWindow(QMainWindow): self.input_medication.setText(medication) self.input_additional.setText(additional) self.input_certificate.setText(certificate) + self.input_custom.setData(custom) self.label_prescriber.setText(self.prescription.prescriber.name) except Exception as e: QMessageBox.warning(self,"Failed to load", "Failed to load the data into the application.") @@ -400,7 +402,8 @@ class MainWindow(QMainWindow): investigation=self.prescription.investigation, medication=self.prescription.medication, additional=self.prescription.additional, - certificate=self.prescription.certificate + certificate=self.prescription.certificate, + custom=self.prescription.custom ) def update_instance(self): @@ -424,7 +427,8 @@ class MainWindow(QMainWindow): investigation=self.input_investigation.toPlainText(), medication=self.input_medication.toPlainText(), additional=self.input_additional.toPlainText(), - certificate=self.input_certificate.toPlainText() + certificate=self.input_certificate.toPlainText(), + custom=self.input_custom.getData() ) except Exception as e: QMessageBox.critical(self,"Failed", "Critical failure happned. Please check console for more info.") @@ -856,6 +860,11 @@ class MainWindow(QMainWindow): layout_attachment2.addWidget(button_remove) layout_attachment2.addWidget(button_save) + tab_custom=QWidget(self) + layout_custom=QVBoxLayout(tab_custom) + self.input_custom=CustomForm() + layout_custom.addWidget(self.input_custom) + tab=QTabWidget(self) tab.addTab(tab_info, "Patient") tab.addTab(tab_note, "Clinical") @@ -865,6 +874,8 @@ class MainWindow(QMainWindow): tab.addTab(tab_medication, "Medication") tab.addTab(tab_additional, "Additional") tab.addTab(tab_certificate, "Certificate") + if(config["enable_form"]): + tab.addTab(tab_custom, "Custom") tab.addTab(tab_attachment, "Attachment") self.setCentralWidget(tab) -- 2.39.5