from __future__ import annotations import pathlib from ..Qt import QtWidgets, QtCore class FileDialog(QtWidgets.QFileDialog): last_path = None def __init__(self, directory=None, caption=None, filter='', mode='open', parent=None): super().__init__(parent=parent) self.setOption(QtWidgets.QFileDialog.DontUseNativeDialog, True) self.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen if mode == 'open' else QtWidgets.QFileDialog.AcceptSave) self.setWindowTitle(caption) if directory: self.setDirectory(str(directory)) elif self.last_path is not None: self.setDirectory(str(FileDialog.last_path)) self.setNameFilters(filter.split(';;')) file_tree = self.findChild(QtWidgets.QTreeView, 'treeView') file_tree.setSortingEnabled(True) for i in range(file_tree.header().count()): file_tree.header().setSectionResizeMode(i, 0) file_tree.model().sort(0) file_list = self.findChild(QtWidgets.QListView, 'listView') file_list.model().sort(0) line = QtWidgets.QFrame(self) line.setFrameShape(line.HLine) line.setFrameShadow(line.Sunken) self.layout().addWidget(line, self.layout().rowCount(), 0, 1, self.layout().columnCount()) def save_file(self) -> pathlib.Path | None: outfile = self.selectedFiles() if outfile: if self.is_valid(outfile[0]): return pathlib.Path(outfile[0]) else: _ = QtWidgets.QMessageBox.warning(self, 'Save file', 'Filename contains one or more invalid character: / * < > \\ | : "') return @staticmethod def is_valid(filename: str): return True bad_character = r'/*<>\|:"' for c in bad_character: if c in filename: return False return True def close(self): FileDialog.last_path = self.directory() super().close() class OpenFileDialog(FileDialog): def __init__(self, **kwargs): super().__init__(**kwargs) self.setFileMode(QtWidgets.QFileDialog.ExistingFiles) self.checkBox = QtWidgets.QCheckBox(self) self.checkBox.setChecked(False) self.checkBox.setText('Use existing graph') self.checkBox.stateChanged.connect(self.checkbox_state) self.layout().addWidget(self.checkBox) self.comboBox = QtWidgets.QComboBox(self) self.comboBox.setEnabled(False) self.layout().addWidget(self.comboBox) self.add_to_graph = None def set_graphs(self, graphs): self.comboBox.blockSignals(True) for gid, name in graphs: self.comboBox.addItem(name, userData=gid) self.comboBox.blockSignals(False) if not self.comboBox.count(): self.comboBox.hide() self.checkBox.hide() def checkbox_state(self, checked: QtCore.Qt.CheckState): if checked == QtCore.Qt.Checked: self.comboBox.setEnabled(True) self.add_to_graph = self.comboBox.currentData() else: self.comboBox.setEnabled(False) self.add_to_graph = None @QtCore.pyqtSlot(int, name='on_comboBox_currentIndexChanged') def graph_changed(self, idx: int): self.add_to_graph = self.comboBox.itemData(idx) class SaveDirectoryDialog(FileDialog): def __init__(self, **kwargs): super().__init__(**kwargs) self.setOption(QtWidgets.QFileDialog.DontConfirmOverwrite, False) self.setAcceptMode(QtWidgets.QFileDialog.AcceptSave) lay = self.layout() self.label = QtWidgets.QLabel(self) self.label.setTextFormat(QtCore.Qt.RichText) self.label.setText('Use <label> as placeholder in filename. (e.g. t1_<label>.dat)') lay.addWidget(self.label, lay.rowCount(), 0, 1, lay.columnCount()) line = QtWidgets.QFrame(self) line.setFrameShape(line.HLine) line.setFrameShadow(line.Sunken) lay.addWidget(line, lay.rowCount(), 0, 1, lay.columnCount()) h_layout = QtWidgets.QHBoxLayout() h_layout.setContentsMargins(0, 0, 0, 0) h_layout.setSpacing(3) self.checkBox = QtWidgets.QCheckBox(self) self.checkBox.setChecked(True) self.checkBox.setText('Replace spaces with _') h_layout.addWidget(self.checkBox) self.agr_cb = QtWidgets.QCheckBox(self) self.agr_cb.setChecked(True) self.agr_cb.setText('Save graph as Grace file') h_layout.addWidget(self.agr_cb) self.fit_cb = QtWidgets.QCheckBox(self) self.fit_cb.setChecked(True) self.fit_cb.setText('Save fit parameter') h_layout.addWidget(self.fit_cb) lay.addLayout(h_layout, lay.rowCount(), 0, 1, lay.columnCount()) self.setWindowTitle('Save') self.setNameFilters(['All files (*.*)', 'Session file (*.nmr)', 'Text file (*.dat)', 'HDF file (*.h5)', 'Grace files (*.agr)'])