]> Softwares of Agnibho - medscript.git/blob - window.py
Added toolbar icons
[medscript.git] / window.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 import os, sys, datetime, dateutil.parser, webbrowser
9 from PyQt6.QtCore import QDateTime, QSize, pyqtSignal
10 from PyQt6.QtWidgets import QWidget, QMainWindow, QMessageBox, QLabel, QPushButton, QLineEdit, QTextEdit, QDateTimeEdit, QListWidget, QComboBox, QCheckBox, QVBoxLayout, QHBoxLayout, QFormLayout, QToolBar, QTabWidget, QStatusBar, QFileDialog
11 from PyQt6.QtGui import QAction, QIcon
12 from pathlib import Path
13 from hashlib import md5
14 from prescription import Prescription
15 from renderer import Renderer
16 from filehandler import FileHandler
17 from renderbox import RenderBox
18 from setting import EditPrescriber
19 from viewbox import ViewBox
20
21 class MainWindow(QMainWindow):
22
23 signal_view=pyqtSignal(str)
24
25 current_file=FileHandler()
26 prescription=Prescription()
27 renderer=Renderer()
28 save_state=md5("".encode()).hexdigest()
29
30 def cmd_new(self):
31 self.prescription.set_data()
32 self.input_attachment.clear()
33 self.load_interface()
34 self.save_state=md5("".encode()).hexdigest()
35
36 def cmd_open(self):
37 try:
38 self.current_file.set_file(QFileDialog.getOpenFileName()[0])
39 self.current_file.open()
40 self.prescription.read_from(os.path.join(self.current_file.directory.name,"prescription.json"))
41 self.load_interface_from_instance()
42 self.save_state=md5(self.prescription.get_json().encode()).hexdigest()
43 self.load_attachment(self.current_file.list())
44 except Exception as e:
45 QMessageBox.warning(self,"Open failed", "Failed to open file.")
46 print(e)
47
48 def cmd_save(self):
49 try:
50 if not os.path.exists(self.current_file.file):
51 self.current_file.set_file(QFileDialog.getSaveFileName()[0])
52 for i in range(self.input_attachment.count()):
53 self.current_file.copy(self.input_attachment.item(i).text())
54 self.update_instance()
55 self.prescription.write_to(os.path.join(self.current_file.directory.name, "prescription.json"))
56 self.current_file.save()
57 self.load_interface_from_instance()
58 self.save_state=md5(self.prescription.get_json().encode()).hexdigest()
59 except Exception as e:
60 QMessageBox.warning(self,"Save failed", "Failed to save file.")
61 print(e)
62
63 def cmd_save_as(self):
64 self.current_file.set_file(QFileDialog.getSaveFileName()[0])
65 Path(self.current_file.file).touch()
66 self.cmd_save()
67
68 def cmd_refresh(self):
69 self.update_instance()
70 self.load_interface_from_instance()
71
72 def cmd_quit(self):
73 sys.exit()
74
75 def cmd_render(self):
76 self.update_instance()
77 if(self.save_state==md5(self.prescription.get_json().encode()).hexdigest()):
78 target=self.renderer.render(self.current_file.directory.name)
79 self.signal_view.emit(target)
80 self.renderbox.show()
81 else:
82 QMessageBox.information(self,"Save first", "Please save the file before rendering.")
83
84 def cmd_prescriber(self):
85 self.edit_prescriber.show()
86
87 def cmd_about(self):
88 self.viewbox.open(os.path.join("resource", "about.html"))
89 self.viewbox.show()
90
91 def cmd_help(self):
92 self.viewbox.open(os.path.join("resource", "help.html"))
93 self.viewbox.show()
94
95 def load_interface(self, file="", date=None, id="", name="", age="", sex="", address="", contact="", extra="", mode="", daw="", note="", report="", investigation="", medication="", advice=""):
96 try:
97 self.statusbar.showMessage(self.current_file.file)
98 if date is None:
99 d=QDateTime.currentDateTime()
100 else:
101 try:
102 pdate=dateutil.parser.parse(date)
103 d=QDateTime.fromString(pdate.strftime("%Y-%m-%d %H:%M:%S"), "yyyy-MM-dd hh:mm:ss")
104 except Exception as e:
105 QMessageBox.warning(self,"Failed to load", str(e))
106 raise(e)
107 self.input_date.setDateTime(d)
108 self.input_id.setText(id)
109 self.input_name.setText(name)
110 self.input_age.setText(age)
111 self.input_sex.setCurrentText(sex)
112 self.input_address.setText(address)
113 self.input_contact.setText(contact)
114 self.input_extra.setText(extra)
115 self.input_mode.setCurrentText(mode)
116 self.input_daw.setChecked(bool(daw))
117 self.input_note.setText(note)
118 self.input_report.setText(report)
119 self.input_investigation.setText(investigation)
120 self.input_medication.setText(medication)
121 self.input_advice.setText(advice)
122 except Exception as e:
123 QMessageBox.warning(self,"Failed to load", "Failed to load the data into the application.")
124 print(e)
125
126 def load_interface_from_instance(self):
127 self.load_interface(
128 file=self.prescription.file,
129 date=self.prescription.date,
130 id=self.prescription.id,
131 name=self.prescription.name,
132 age=self.prescription.age,
133 sex=self.prescription.sex,
134 address=self.prescription.address,
135 contact=self.prescription.contact,
136 extra=self.prescription.extra,
137 mode=self.prescription.mode,
138 daw=self.prescription.daw,
139 note=self.prescription.note,
140 report=self.prescription.report,
141 investigation=self.prescription.investigation,
142 medication=self.prescription.medication,
143 advice=self.prescription.advice
144 )
145
146 def update_instance(self):
147 try:
148 self.prescription.set_data(
149 date=self.input_date.dateTime().toString("yyyy-MM-dd hh:mm:ss"),
150 id=self.input_id.text(),
151 name=self.input_name.text(),
152 age=self.input_age.text(),
153 sex=self.input_sex.currentText(),
154 address=self.input_address.text(),
155 contact=self.input_contact.text(),
156 extra=self.input_extra.toPlainText(),
157 mode=self.input_mode.currentText(),
158 daw=self.input_daw.isChecked(),
159 note=self.input_note.toPlainText(),
160 report=self.input_report.toPlainText(),
161 investigation=self.input_investigation.toPlainText(),
162 medication=self.input_medication.toPlainText(),
163 advice=self.input_advice.toPlainText()
164 )
165 except Exception as e:
166 QMessageBox.critical(self,"Failed", "Critical failure happned. Please check console for more info.")
167 print(e)
168
169 def add_attachment(self):
170 try:
171 new=QFileDialog.getOpenFileName()[0]
172 if new:
173 self.input_attachment.addItem(new)
174 except Exception as e:
175 QMessageBox.warning(self,"Attach failed", "Failed to attach file.")
176 print(e)
177
178 def remove_attachment(self):
179 self.input_attachment.takeItem(self.input_attachment.currentRow())
180
181 def open_attachment(self):
182 webbrowser.open(self.input_attachment.currentItem().text())
183
184 def load_attachment(self, attachments):
185 for attach in attachments:
186 self.input_attachment.addItem(attach)
187
188 def __init__(self, *args, **kwargs):
189 super().__init__(*args, **kwargs)
190
191 self.setWindowTitle("MedScript")
192 self.setGeometry(100, 100, 600, 400)
193
194 icon_open=QIcon("resource/icon_open.svg")
195 icon_save=QIcon("resource/icon_save.svg")
196 icon_render=QIcon("resource/icon_render.svg")
197 icon_refresh=QIcon("resource/icon_refresh.svg")
198
199 action_new=QAction("New", self)
200 action_new.triggered.connect(self.cmd_new)
201 action_open=QAction("Open", self)
202 action_open2=QAction(icon_open, "Open", self)
203 action_open.triggered.connect(self.cmd_open)
204 action_open2.triggered.connect(self.cmd_open)
205 action_save=QAction("Save", self)
206 action_save2=QAction(icon_save, "Save", self)
207 action_save.triggered.connect(self.cmd_save)
208 action_save2.triggered.connect(self.cmd_save)
209 action_save_as=QAction("Save As", self)
210 action_save_as.triggered.connect(self.cmd_save_as)
211 action_refresh=QAction("Refresh", self)
212 action_refresh2=QAction(icon_refresh, "Refresh", self)
213 action_refresh.triggered.connect(self.cmd_refresh)
214 action_refresh2.triggered.connect(self.cmd_refresh)
215 action_quit=QAction("Quit", self)
216 action_quit.triggered.connect(self.cmd_quit)
217 action_render=QAction("Render", self)
218 action_render2=QAction(icon_render, "Render", self)
219 action_render.triggered.connect(self.cmd_render)
220 action_render2.triggered.connect(self.cmd_render)
221 action_prescriber=QAction("Prescriber", self)
222 action_prescriber.triggered.connect(self.cmd_prescriber)
223 action_about=QAction("About", self)
224 action_about.triggered.connect(self.cmd_about)
225 action_help=QAction("Help", self)
226 action_help.triggered.connect(self.cmd_help)
227
228 menubar=self.menuBar()
229 menu_file=menubar.addMenu("File")
230 menu_file.addAction(action_new)
231 menu_file.addAction(action_open)
232 menu_file.addAction(action_save)
233 menu_file.addAction(action_save_as)
234 menu_file.addAction(action_quit)
235 menu_prepare=menubar.addMenu("Prepare")
236 menu_prepare.addAction(action_render)
237 menu_prepare.addAction(action_refresh)
238 menu_prepare.addAction(action_prescriber)
239 menu_help=menubar.addMenu("Help")
240 menu_help.addAction(action_about)
241 menu_help.addAction(action_help)
242
243 toolbar=QToolBar("Main Toolbar", floatable=False, movable=False)
244 toolbar.setIconSize(QSize(16, 16))
245 toolbar.addAction(action_open2)
246 toolbar.addAction(action_save2)
247 toolbar.addAction(action_refresh2)
248 toolbar.addAction(action_render2)
249 self.addToolBar(toolbar)
250
251 tab_info=QWidget(self)
252 layout_info=QFormLayout(tab_info)
253 self.input_date=QDateTimeEdit(self)
254 self.input_date.setDisplayFormat("MMMM dd, yyyy hh:mm a")
255 layout_info.addRow("Date", self.input_date)
256 self.input_id=QLineEdit(self)
257 layout_info.addRow("ID", self.input_id)
258 self.input_name=QLineEdit(self)
259 layout_info.addRow("Name", self.input_name)
260 self.input_age=QLineEdit(self)
261 layout_info.addRow("Age", self.input_age)
262 self.input_sex=QComboBox(self)
263 self.input_sex.addItems(["Male", "Female", "Other"])
264 self.input_sex.setEditable(True)
265 layout_info.addRow("Sex", self.input_sex)
266 self.input_address=QLineEdit(self)
267 layout_info.addRow("Address", self.input_address)
268 self.input_contact=QLineEdit(self)
269 layout_info.addRow("Contact", self.input_contact)
270 self.input_extra=QTextEdit(self)
271 layout_info.addRow("Extra", self.input_extra)
272 self.input_mode=QComboBox(self)
273 self.input_mode.addItems(["In-Person", "Tele-Consultation", "Other"])
274 self.input_mode.setEditable(True)
275 layout_info.addRow("Mode", self.input_mode)
276 self.input_daw=QCheckBox("Dispense as written", self)
277 layout_info.addRow("DAW", self.input_daw)
278
279 tab_note=QWidget(self)
280 layout_note=QVBoxLayout(tab_note)
281 label_note=QLabel("Clinical Notes")
282 self.input_note=QTextEdit(self)
283 layout_note.addWidget(label_note)
284 layout_note.addWidget(self.input_note)
285
286 tab_report=QWidget(self)
287 layout_report=QVBoxLayout(tab_report)
288 label_report=QLabel("Available Reports")
289 self.input_report=QTextEdit(self)
290 layout_report.addWidget(label_report)
291 layout_report.addWidget(self.input_report)
292
293 tab_investigation=QWidget(self)
294 layout_investigation=QVBoxLayout(tab_investigation)
295 label_investigation=QLabel("Recommended Investigations")
296 self.input_investigation=QTextEdit(self)
297 layout_investigation.addWidget(label_investigation)
298 layout_investigation.addWidget(self.input_investigation)
299
300 tab_medication=QWidget(self)
301 layout_medication=QVBoxLayout(tab_medication)
302 label_medication=QLabel("Medication Advice")
303 self.input_medication=QTextEdit(self)
304 layout_medication.addWidget(label_medication)
305 layout_medication.addWidget(self.input_medication)
306
307 tab_advice=QWidget(self)
308 layout_advice=QVBoxLayout(tab_advice)
309 label_advice=QLabel("Additional Advice")
310 self.input_advice=QTextEdit(self)
311 layout_advice.addWidget(label_advice)
312 layout_advice.addWidget(self.input_advice)
313
314 tab_attachment=QWidget(self)
315 layout_attachment=QVBoxLayout(tab_attachment)
316 layout_attachment2=QHBoxLayout()
317 label_attachment=QLabel("Attached files")
318 self.input_attachment=QListWidget(self)
319 button_add=QPushButton("Add")
320 button_add.clicked.connect(self.add_attachment)
321 button_remove=QPushButton("Remove")
322 button_remove.clicked.connect(self.remove_attachment)
323 button_open=QPushButton("Open")
324 button_open.clicked.connect(self.open_attachment)
325 layout_attachment.addWidget(label_attachment)
326 layout_attachment.addLayout(layout_attachment2)
327 layout_attachment.addWidget(self.input_attachment)
328 layout_attachment2.addWidget(button_add)
329 layout_attachment2.addWidget(button_remove)
330 layout_attachment2.addWidget(button_open)
331
332
333 tab=QTabWidget(self)
334 tab.addTab(tab_info, "Patient")
335 tab.addTab(tab_note, "Clinical")
336 tab.addTab(tab_report, "Report")
337 tab.addTab(tab_investigation, "Investigation")
338 tab.addTab(tab_medication, "Medication")
339 tab.addTab(tab_advice, "Advice")
340 tab.addTab(tab_attachment, "Attachment")
341
342 self.setCentralWidget(tab)
343
344 self.statusbar=QStatusBar()
345 self.setStatusBar(self.statusbar)
346
347 self.renderbox=RenderBox()
348 self.signal_view.connect(self.renderbox.update)
349 self.edit_prescriber=EditPrescriber()
350 self.viewbox=ViewBox()
351
352 self.cmd_new()
353 self.show()