from schrodinger.Qt import QtCore
from schrodinger.Qt import QtGui
from schrodinger.Qt import QtWidgets
from schrodinger.Qt.QtCore import Qt
from schrodinger.structure import Structure
[docs]class BaseTable(QtWidgets.QTableWidget):
[docs] def __init__(self, parent=None):
QtWidgets.QTableWidget.__init__(self, parent)
self.setup()
self.reset()
[docs] def reset(self):
self.removeAllRows()
[docs] def removeAllRows(self):
while self.rowCount() > 0:
self.removeRow(0)
[docs] def setup(self):
self.show()
self.setEnabled(True)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.setColumnCount(len(self.header_titles))
self.setHorizontalHeaderLabels(self.header_titles)
header = self.horizontalHeader()
header.setSectionResizeMode(QtWidgets.QHeaderView.Interactive)
vheader = self.verticalHeader()
vheader.setVisible(False)
self.setSortingEnabled(True)
[docs] def keyPressEvent(self, event):
if event.matches(QtGui.QKeySequence.Copy):
mime_data = QtCore.QMimeData()
text = self.getSelectedText()
mime_data.setText(text)
QtWidgets.QApplication.clipboard().setMimeData(mime_data)
[docs] def getSelectedText(self):
items = self.selectedItems()
if not items:
return ''
current_row = items[0].row()
lines = []
line = []
for item in items:
row = item.row()
if row > current_row:
current_row = row
lines.append('\t'.join(line))
line = []
line.append(item.text())
if line:
lines.append('\t'.join(line))
text = '\n'.join(lines)
return text
[docs]class LogTable(BaseTable):
Super = BaseTable
header_titles = ['Time', 'Tag', 'Caller', 'Text']
[docs] def __init__(self, parent=None):
self.log = []
self.Super.__init__(self, parent)
[docs] def setup(self):
self.Super.setup(self)
self.setColumnWidth(0, 100)
self.setColumnWidth(1, 80)
self.setColumnWidth(2, 150)
self.setColumnWidth(3, 500)
[docs] def addEntry(self, entry):
row_idx = self.rowCount()
self.setRowCount(row_idx + 1)
self.setRowHeight(row_idx, 18)
self.setItem(row_idx, 0, QtWidgets.QTableWidgetItem(entry.timestamp))
self.setItem(row_idx, 1, QtWidgets.QTableWidgetItem(entry.tag))
self.setItem(row_idx, 2, QtWidgets.QTableWidgetItem(entry.caller))
self.setItem(row_idx, 3, QtWidgets.QTableWidgetItem(entry.text))
self.resizeRowsToContents()
[docs]class LogTagTable(BaseTable):
Super = BaseTable
header_titles = ['Enable', 'Tag']
[docs] def __init__(self, parent=None):
self.Super.__init__(self, parent)
[docs]def find_signals(obj_name, obj):
signals = []
for name in dir(obj):
attr = getattr(obj, name)
if isinstance(attr, QtCore.pyqtBoundSignal):
signals.append((obj_name, obj, name, attr))
return signals
EXCLUDE_DEEP_FIND_CLASSES = (Structure,)
[docs]def deep_find_signals(obj_name, obj, done_list=None, depth=0):
signals = []
if isinstance(obj, EXCLUDE_DEEP_FIND_CLASSES):
print('Object %s excluded from scanning.' % obj_name)
return signals
if depth > 8:
print('Depth %i in %s' % (depth, obj_name))
if depth > 30:
print('Max depth exceeded.')
return signals
if done_list is None:
done_list = []
try:
for item in done_list:
if obj is item:
return signals
except TypeError:
return signals
done_list.append(obj)
if not hasattr(obj, '__dict__'):
return signals
signals.extend(find_signals(obj_name, obj))
for sub_obj_name, sub_obj in obj.__dict__.items():
if obj_name:
full_name = obj_name + '.' + sub_obj_name
else:
full_name = sub_obj_name
signals.extend(
deep_find_signals(full_name, sub_obj, done_list, depth=depth + 1))
return signals
[docs]class SignalTable(BaseTable):
Super = BaseTable
header_titles = ['Enable', 'Object', 'Signal']
[docs] def __init__(self, parent=None):
self.connected_slots = {}
self.all_slots = {}
self.signals = []
self.Super.__init__(self, parent)
self.cellChanged.connect(self.onCellChanged)
[docs] def setup(self):
self.Super.setup(self)
self.setColumnWidth(0, 50)
self.setColumnWidth(1, 150)
self.setColumnWidth(2, 300)
[docs] def addEntry(self, obj_name, obj, signal_name, signal):
row_idx = self.rowCount()
self.setRowCount(row_idx + 1)
self.setRowHeight(row_idx, 18)
check_item = QtWidgets.QTableWidgetItem()
check_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled |
Qt.ItemIsUserCheckable)
check_item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
check_item.setCheckState(Qt.Unchecked)
check_item.signal = signal
self.setItem(row_idx, 0, check_item)
self.setItem(row_idx, 1, QtWidgets.QTableWidgetItem(obj_name))
self.setItem(row_idx, 2, QtWidgets.QTableWidgetItem(signal_name))
[docs] def onCellChanged(self, row, column):
if column == 0:
item = self.item(row, column)
if item.checkState() == QtCore.Qt.Checked:
self.connectSignal(item.signal)
else:
self.disconnectSignal(item.signal)
[docs] def deepFindSignals(self, obj_name, obj, done_list=None):
return deep_find_signals(obj_name, obj, done_list)
[docs] def scan(self, obj, exclude_objs):
self.disconnectSignals()
self.reset()
signals = self.deepFindSignals('', obj, exclude_objs)
self.signals = signals
for obj_name, obj, signal_name, signal in signals:
self.addEntry(obj_name, obj, signal_name, signal)
[docs] def registerSignals(self, slot_factory):
for obj_name, obj, signal_name, signal in self.signals:
slot = slot_factory(obj_name, signal_name, signal)
self.all_slots[signal] = slot
[docs] def deregisterSignals(self):
self.disconnectSignals()
for signal in list(self.all_slots):
self.all_slots.pop(signal)
[docs] def connectSignals(self):
for signal in list(self.connected_slots):
self.connectSignal(signal)
[docs] def disconnectSignals(self):
for signal in list(self.connected_slots):
self.disconnectSignal(signal)
[docs] def connectSignal(self, signal):
if signal in self.connected_slots:
return
slot = self.all_slots[signal]
signal.connect(slot)
self.connected_slots[signal] = slot
[docs] def disconnectSignal(self, signal):
if signal not in self.connected_slots:
return
slot = self.connected_slots.pop(signal)
signal.disconnect(slot)
[docs] def applyFilter(self, filter_string):
for row_idx in range(self.rowCount()):
obj_name = self.item(row_idx, 1).text().lower()
signal_name = self.item(row_idx, 2).text().lower()
filter_string = filter_string.lower()
found = filter_string in obj_name or filter_string in signal_name
self.setRowHidden(row_idx, not found)
class _HistoryLineEdit(QtWidgets.QLineEdit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.history = []
self.history_index = 0
self.temp_text = ''
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Up:
if self.history_index < len(self.history):
if self.history_index == 0:
self.temp_text = self.text()
self.history_index += 1
text = self.history[-1 * self.history_index]
self.setText(text)
elif e.key() == QtCore.Qt.Key_Down:
if self.history_index > 0:
text = self.history[-1 * self.history_index]
self.history_index -= 1
else:
text = self.temp_text
self.setText(text)
else:
super().keyPressEvent(e)