Source code for schrodinger.ui.qt.presets.manage_presets_dialog

import os
import typing
import traceback

from schrodinger.ui.qt import basewidgets, filedialog
from schrodinger.ui.qt.presets import manage_presets_dialog_ui
from schrodinger.ui.qt.mapperwidgets import plptable
from schrodinger.Qt import QtWidgets
from schrodinger.models import parameters, mappers
from schrodinger.models.presets import Direction

IN_DEV_MODE = 'SCHRODINGER_SRC' in os.environ


[docs]class PresetRowModel(parameters.CompoundParam): preset_name: str is_default: bool
[docs]class ManagePresetsModel(parameters.CompoundParam): preset_names: typing.List[PresetRowModel] selected_names: typing.List[PresetRowModel]
[docs]class ManagePresetsTableSpec(plptable.TableSpec): preset_name = plptable.FieldColumn( PresetRowModel.preset_name, sample_data='OptionInputsOptionInputs') is_default = plptable.FieldColumn( PresetRowModel.is_default, sample_data='(User default)')
[docs] @is_default.data_method() def displayDefault(self, is_default): if is_default: return "(user default)" else: return ""
[docs]class ManagePresetsDialog(mappers.MapperMixin, basewidgets.BaseDialog): ui_module = manage_presets_dialog_ui model_class = ManagePresetsModel
[docs] def __init__(self, preset_manager, preset_model): """ :param preset_manager: The preset manager to use for saving a preset. :type preset_manager: schrodinger.models.tasks.presets.PresetManager :param preset_model: The model to use for applying any presets. :type preset_model: schrodinger.models.parameters.CompoundParam """ self._preset_manager = preset_manager self.preset_model = preset_model super().__init__()
[docs] def initSetUp(self): super().initSetUp() self._all_options_table = plptable.PLPTableWidget( spec=ManagePresetsTableSpec()) self._styleAllOptionsTable() self._all_options_table.view.setSelectionMode( QtWidgets.QAbstractItemView.SingleSelection) self.ui.delete_btn.clicked.connect(self._deleteSelected) self.ui.clear_or_set_default_btn.clicked.connect( self._clearOrSetDefault) self.ui.apply_btn.clicked.connect(self._applySelectedPreset) self.ui.up_arrow_btn.clicked.connect( lambda: self._movePreset(Direction.UP)) self.ui.down_arrow_btn.clicked.connect( lambda: self._movePreset(Direction.DOWN)) self.ui.export_btn.clicked.connect(self._exportPresets) self.ui.import_btn.clicked.connect(self._importPresets) # Emojis for now, eventually should be up / down arrow icons self.ui.up_arrow_btn.setText("⬆") self.ui.down_arrow_btn.setText("⬇") self.ui.up_arrow_btn.setEnabled(False) self.ui.down_arrow_btn.setEnabled(False) self._hideNotImplementedFeatures()
def _styleAllOptionsTable(self): self._all_options_table.view.setShowGrid(False) self._all_options_table.view.horizontalHeader().hide() def _hideNotImplementedFeatures(self): self.ui.options_editor_widget.setVisible(False)
[docs] def initLayOut(self): super().initLayOut() self.ui.all_options_table_layout.addWidget(self._all_options_table)
[docs] def initFinalize(self): super().initFinalize() default = self._preset_manager.getDefaultPreset() self._loadOrdering(select=default)
[docs] def defineMappings(self): return [ (self._all_options_table, self.model_class.preset_names), (self._all_options_table.selection_target, self.model_class.selected_names), # yapf: disable (self._setExportEnable, self.model_class.preset_names) ]
[docs] def getSignalsAndSlots(self, model): return [(model.selected_namesChanged, self._updateButtons), (model.preset_namesChanged, self._setExportEnable)]
def _deleteSelected(self): if len(self.model.selected_names) == 1: name = self.model.selected_names[0].preset_name self._preset_manager.deletePreset(name) self._all_options_table.removeSelectedParams() def _setExportEnable(self): if len(self.model.preset_names) > 0: self.ui.export_btn.setEnabled(True) else: self.ui.export_btn.setEnabled(False) def _updateButtons(self): selected_names = self.model.selected_names if len(selected_names) == 1: if selected_names[0].is_default: self.ui.clear_or_set_default_btn.setText('Clear Default') self.ui.up_arrow_btn.setEnabled(False) self.ui.down_arrow_btn.setEnabled(False) else: selected_index = self.model.preset_names.index( selected_names[0]) top_no_default = selected_index == 0 top_with_default = self._preset_manager.getDefaultPreset( ) and selected_index == 1 top = top_no_default or top_with_default bottom = selected_index == len(self.model.preset_names) - 1 # If the selection is at the top or bottom disable clicking up and down # respectively self.ui.up_arrow_btn.setEnabled(not top) self.ui.down_arrow_btn.setEnabled(not bottom) self.ui.clear_or_set_default_btn.setText('Set as Default') def _clearOrSetDefault(self): """ If the default preset is currently selected clear its default status. If a non-default preset is currently selected set it as the default and reorder the table to put the new default on top. """ selected_names = self.model.selected_names if len(selected_names) == 1: selected_row = selected_names[0] if selected_row.is_default: self._clearDefault(selected_row) else: self._setDefault(selected_row) def _clearDefault(self, selected_row): """ Assumes the given row is the only selected row and is the default preset """ selected_row.is_default = False self._preset_manager.clearDefaultPreset() def _setDefault(self, selected_row): """ Assumes the given row is the only selected row and is not the default preset """ default_name = self._preset_manager.getDefaultPreset() for row in self.model.preset_names: if row.preset_name == default_name: row.is_default = False # Put the new default at the top, the old default will be one # below. Assumes on init any default is always on top. selected_index = self.model.preset_names.index(selected_row) selected_row.is_default = True new_default = self.model.preset_names.pop(selected_index) self.model.preset_names.insert(0, new_default) self._all_options_table.setSelectedParams(self.model.preset_names[:1]) self._preset_manager.setDefaultPreset(selected_row.preset_name) def _applySelectedPreset(self): selected_names = self.model.selected_names if len(selected_names) == 1: name = selected_names[0].preset_name try: self._preset_manager.loadPreset(name, self.preset_model) except Exception as e: self.error( "Encountered an error while trying to load the " "settings. They are either out of date or corrupted.") if IN_DEV_MODE: traceback.print_stack() def _movePreset(self, direction): selected_names = self.model.selected_names if len(selected_names) == 1: selected_name = selected_names[0].preset_name self._preset_manager.movePreset(selected_name, direction) self._loadOrdering(select=selected_name) def _loadOrdering(self, select=None): """ Populates the table by requesting the ordering from the manager. :param select: The name of the preset to be selected after the table is populated :type select: str """ preset_rows = [] default_name = self._preset_manager.getDefaultPreset() for name in self._preset_manager.getAvailablePresets(): default = default_name == name row = PresetRowModel(preset_name=name, is_default=default) preset_rows.append(row) self.model.preset_names = preset_rows if select: names = [row.preset_name for row in self.model.preset_names] index = names.index(select) select_row = self.model.preset_names[index:index + 1] self._all_options_table.setSelectedParams(select_row) def _exportPresets(self): """ Opens a save file dialog to export the selected file. """ preset_names = self.model.preset_names if len(preset_names) > 0: export_fname = filedialog.get_save_file_name( parent=self, caption='Export Preset', filter='Panel Options files (*.opts)', accept_label='Export', default_filename='panel_options') if export_fname: self._preset_manager.exportPresets(export_fname) else: raise RuntimeError('No available presets to export') def _importPresets(self): """ Opens an open file dialog to import the selected file. """ import_fname = filedialog.get_open_file_name( parent=self, caption='Import Preset', filter='Panel Options files (*.opts)', accept_label='Import') if import_fname: try: self._preset_manager.importPresets(import_fname, self.preset_model) except Exception as e: self.error("Encountered an error while trying to import the " "options. They are either out of date or corrupted.") if IN_DEV_MODE: traceback.print_stack() else: self._loadOrdering()
if __name__ == "__main__": dlg = ManagePresetsDialog()