save_area_file_dialog.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. from PyQt5.QtWidgets import QMainWindow, QWidget, QVBoxLayout, QComboBox, QGroupBox, QListWidget, QAbstractItemView,\
  2. QListWidgetItem, QPushButton, QDesktopWidget, QMessageBox
  3. from PyQt5.QtCore import pyqtSlot, pyqtSignal
  4. from view.gui.filesystem_selectors import FileSaver
  5. import pathlib as pl
  6. class AbstractSaveROIsDialog(QMainWindow):
  7. return_choices_signal = pyqtSignal(list, str, name="choices")
  8. def __init__(self, metadata, roi_labels, extension, file_filter):
  9. super().__init__()
  10. self.metadata = metadata
  11. self.roi_labels = roi_labels
  12. self.extension = extension
  13. self.file_filter = file_filter
  14. def initui(self, data_selected, rois_selected, data_chooser_title, roi_chooser_title,
  15. file_selector_dialog_title, file_selector_widget_title, save_button_title, window_title):
  16. central_widget = QWidget(self)
  17. main_vbox = QVBoxLayout(central_widget)
  18. data_chooser_group = QGroupBox(data_chooser_title)
  19. data_chooser_vbox = QVBoxLayout(data_chooser_group)
  20. self.data_chooser = QComboBox(data_chooser_group)
  21. self.data_chooser.addItems(self.metadata["Label to use"].values)
  22. self.data_chooser.setCurrentText(str(data_selected[0]))
  23. self.data_chooser.setDuplicatesEnabled(False)
  24. self.data_chooser.activated.connect(self.refresh_filename)
  25. data_chooser_vbox.addWidget(self.data_chooser)
  26. main_vbox.addWidget(data_chooser_group)
  27. roi_chooser_group = QGroupBox(roi_chooser_title)
  28. roi_chooser_vbox = QVBoxLayout(roi_chooser_group)
  29. self.roi_chooser = QListWidget(self)
  30. self.roi_chooser.setSelectionMode(QAbstractItemView.MultiSelection)
  31. for poly_roi in self.roi_labels:
  32. list_item = QListWidgetItem(poly_roi, parent=self.roi_chooser, type=0)
  33. if poly_roi in rois_selected:
  34. list_item.setSelected(True)
  35. self.roi_chooser.addItem(list_item)
  36. roi_chooser_vbox.addWidget(self.roi_chooser)
  37. main_vbox.addWidget(roi_chooser_group)
  38. save_mode_group = QGroupBox("Choose whether to save for only this "
  39. "measurement or all measurements of this animal")
  40. save_mode_vbox = QVBoxLayout(save_mode_group)
  41. self.save_mode_chooser = QComboBox(save_mode_group)
  42. self.save_mode_chooser.addItems(["Save FOR ALL measurements of this animal",
  43. "Save ONLY FOR THIS measurement of this animal"])
  44. self.save_mode_chooser.setCurrentIndex(0)
  45. self.save_mode_chooser.activated.connect(self.refresh_filename)
  46. save_mode_vbox.addWidget(self.save_mode_chooser)
  47. main_vbox.addWidget(save_mode_group)
  48. self.file_selector = FileSaver(widget_title=file_selector_widget_title, parent=self,
  49. dialog_title=file_selector_dialog_title, filter=self.file_filter
  50. )
  51. self.refresh_filename(0)
  52. main_vbox.addWidget(self.file_selector)
  53. save_button = QPushButton(save_button_title)
  54. save_button.clicked.connect(self.return_choices)
  55. main_vbox.addWidget(save_button)
  56. self.setCentralWidget(central_widget)
  57. self.setWindowTitle(window_title)
  58. self.setGeometry(300, 300, 500, 700)
  59. self.center()
  60. def center(self):
  61. qr = self.frameGeometry()
  62. cp = QDesktopWidget().availableGeometry().center()
  63. qr.moveCenter(cp)
  64. self.move(qr.topLeft())
  65. @classmethod
  66. def get_destination_directory_flag_name(cls):
  67. return None
  68. @pyqtSlot(int, name="refresh filename when data or mode changes")
  69. def refresh_filename(self, index):
  70. current_label = self.data_chooser.currentText()
  71. current_metadata_row = self.metadata.loc[self.metadata["Label to use"] == current_label, :].iloc[0]
  72. choice_mode = self.save_mode_chooser.currentIndex()
  73. animal = current_metadata_row['STG_ReportTag']
  74. measurement_label = current_metadata_row['Measurement\nLabel']
  75. if choice_mode == 0:
  76. filename = f"{animal}{self.extension}"
  77. else:
  78. filename = f"{animal}_{measurement_label}{self.extension}"
  79. destination_dir = pl.Path(current_metadata_row[self.get_destination_directory_flag_name()])
  80. default_filename = str(destination_dir / filename)
  81. self.file_selector.dialogDefaultPath = default_filename
  82. self.file_selector.setText(default_filename)
  83. def return_choices(self):
  84. chosen_rois = [x.text() for x in self.roi_chooser.selectedItems()]
  85. target_filename = self.file_selector.getText()
  86. if len(chosen_rois) > 0:
  87. self.return_choices_signal.emit(chosen_rois, target_filename)
  88. self.close()
  89. else:
  90. QMessageBox.critical(self, "IO Error", "No ROIs selected. Please select at least one!")
  91. class SaveAreaFileDialog(AbstractSaveROIsDialog):
  92. def __init__(self, metadata, poly_roi_labels, data_selected, poly_rois_selected):
  93. super().__init__(metadata, poly_roi_labels, extension=".area.tif", file_filter="AREA files (*tif)")
  94. self.initui(data_selected=data_selected, rois_selected=poly_rois_selected,
  95. data_chooser_title="Choose the measurement for which area file is to be saved",
  96. roi_chooser_title="Choose the polygon ROIS, the union of which will form the area",
  97. file_selector_widget_title="Select the folder and filename into which the area file is to be saved",
  98. file_selector_dialog_title="Select where the area file is to be saved",
  99. save_button_title="Save area file for VIEW",
  100. window_title='Save area file for VIEW')
  101. @classmethod
  102. def get_destination_directory_flag_name(cls):
  103. return "STG_OdorAreaPath"
  104. class SaveCircleROIsFileDialog(AbstractSaveROIsDialog):
  105. def __init__(self, metadata, circle_roi_labels, data_selected, circle_rois_selected):
  106. super().__init__(metadata, circle_roi_labels, extension=".roi", file_filter="Roi files (*roi)")
  107. self.initui(data_selected=data_selected, rois_selected=circle_rois_selected,
  108. data_chooser_title="Choose the measurement for which ROIs are to be saved",
  109. roi_chooser_title="Choose the circle ROIs to be saved",
  110. file_selector_widget_title="Select the folder and filename into which the ROIs are to be saved",
  111. file_selector_dialog_title="Select where the ROIs are to be saved",
  112. save_button_title="Save ROIs for VIEW",
  113. window_title="Save ROIs for VIEW")
  114. @classmethod
  115. def get_destination_directory_flag_name(cls):
  116. return "STG_OdormaskPath"
  117. class SaveAllROIsFileDialog(AbstractSaveROIsDialog):
  118. def __init__(self, metadata, roi_labels, data_selected, roi_labels_selected):
  119. super().__init__(metadata, roi_labels, extension=".roi", file_filter="ROI files (*roi)")
  120. self.initui(data_selected=data_selected, rois_selected=roi_labels_selected,
  121. data_chooser_title="Choose the measurement for which ROIs are to be saved",
  122. roi_chooser_title="Choose the ROIs to be saved",
  123. file_selector_widget_title="Select the folder and filename into which the ROIs are to be saved",
  124. file_selector_dialog_title="Select where the ROIs are to be saved",
  125. save_button_title="Save ROI for VIEW",
  126. window_title="Save ROI for VIEW")
  127. @classmethod
  128. def get_destination_directory_flag_name(cls):
  129. return "STG_OdormaskPath"