Source code for schrodinger.project.manager

from schrodinger import get_maestro
from schrodinger.project import ProjectException
from schrodinger.project import utils as project_utils
from schrodinger.Qt import QtCore

maestro = get_maestro()


[docs]class EntryGroupManager(QtCore.QObject): """ Manage interactions with an entry group specified by a unique name. The manager is necessary because the entry group object itself may become inaccessible and change its properties if it loses all of its entries. """ groupTitleChanged = QtCore.pyqtSignal(str)
[docs] def __init__(self, parent=None, group_name=None, parent_group_name=None): """ Initialize this object by specifying the unique name of the managed entry group. """ super().__init__(parent=parent) if group_name is None: group_name = project_utils.generate_unique_group_name() self._name = group_name self._parent_group_name = parent_group_name self._title = group_name self._group_empty = bool(self.group) if maestro: maestro.project_update_callback_add(self.onProjectUpdate)
@property def group(self): """ Return the entry group being managed if it is accessible. This is important, for example, if all of the entries are removed from an entry group. :return: The entry group, if it exists in the project. :rtype: project.EntryGroup or None """ if maestro: return project_utils.get_entry_group(self._name) @property def name(self): """ :return: the unique entry group name :rtype: str """ return self._name @property def parent_group(self): group = self.group if group: return group.getParentGroup() @property def parent_group_name(self): """ :return: the unique name of the parent group, if any :rtype: str """ return self._parent_group_name @property def title(self): """ Return the title stored with this manager. By default it is the group name that this manager was initialized with, but it can be set directly by calling `setTitle`. It should be automatically updated via maestro callback if the entry group title is changed by the user in the project table. :return: the entry group name :rtype: str """ return self._title @title.setter def title(self, title): """ Set the title of the entry group. Even if the group is empty (and therefore not active), cache the title string within this manager so that it can be applied to the group when it becomes active again. :param title: the new title :type title: str """ self._title = title if self.group: self.group.title = title
[docs] def moveToGroup(self, entry_ids): """ Move the specified entry IDs to this group. This is preferred over row.moveToGroup if `parent_group_name` is specified, because it will create the group with the correct nesting. """ entry_ids = list(entry_ids) # in case it's exhaustible pg_name = self._parent_group_name if pg_name and self.group is None: # If it's a child group and doesn't exist, need to create it if project_utils.get_entry_group(pg_name) is None: # Recreate parent group if it doesn't exist by moving first row row = project_utils.get_row(entry_ids[0]) row.moveToGroup(pg_name) project_utils.create_child_group(entry_ids=entry_ids, parent_group_name=pg_name, group_name=self.name) else: # If group already exists or there's no parent group for entry in project_utils.get_rows(entry_ids): entry.moveToGroup(self.name)
def _writeTitleToGroup(self): """ Update the managed entry group's title to be the title string saved on this manager. This method should automatically be called when the entry group transitions from containing no entries to containing at least one entry. """ if self.group: self.group.title = self._title def _readTitleFromGroup(self): """ Set the `_title` attribute to the managed entry group's title. This method should be called automatically when the entry group's name changes while contains at least one entry. """ if self.group: self._title = self.group.title self.groupTitleChanged.emit(self._title)
[docs] def onProjectUpdate(self): """ Respond to changes in the Maestro project by updating locally-cached variables. Meant to be called from a Maestro callback. """ try: group = self.group except ProjectException: # Prevent traceback reported in PANEL-16311 return with maestro.IgnoreProjectUpdate(self.onProjectUpdate): if group and not self._group_empty: # Keep the stored group title up to date, in case it was changed # by the user in the project table self._readTitleFromGroup() elif group and self._group_empty: # Update the group title from the stored value. This is # necessary after the the group has had no entries in it, as # empty groups will forget their titles self._group_empty = False self._writeTitleToGroup() else: self._group_empty = True parent_group = self.parent_group if parent_group: self._parent_group_name = parent_group.name