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

import os
import traceback
import typing

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

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()