Source code for schrodinger.ui.sequencealignment.jobs_gui
"""
Implementation of Qt dialog boxes used by multiple sequence viewer.
Copyright Schrodinger, LLC. All rights reserved.
"""
# Contributors: Piotr Rotkiewicz
from schrodinger.Qt import QtCore
from schrodinger.Qt import QtGui
from schrodinger.Qt import QtWidgets
from schrodinger.ui.qt.appframework import ConfigDialog
# This variable is a dictionary so that MSV works when it is embedded into more than one script:
# (previously deletion of a script that uses MSV could have produced "underlying C/C++ object has been deleted" errors)
_JOB_PROGRESS_DIALOGS_BY_PARENT = {}
_JOB_SETTINGS_DIALOGS_BY_PARENT = {}
[docs]class JobProgressDialog(QtWidgets.QDialog):
"""
This class implements a simple job progress dialog.
"""
[docs] def __init__(self, parent):
# Initialize base class.
QtWidgets.QDialog.__init__(self, parent)
#: Text document keeping the job log.
self.text_document = QtGui.QTextDocument(self)
#: Text edit widget that displays self.text_document.
self.text_edit = QtWidgets.QTextEdit(self)
self.text_edit.setDocument(self.text_document)
self.text_edit.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
self.text_edit.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
#: Dialog layout.
self.layout = QtWidgets.QVBoxLayout(self)
self.layout.addWidget(self.text_edit)
#: Dialog push button.
self.button = QtWidgets.QPushButton(self)
self.button.setText("Close")
self.button.setAutoDefault(False)
self.button.clicked.connect(self.endJob)
self.bottom_layout = QtWidgets.QHBoxLayout()
#: Push button box.
self.dialog_button_box = QtWidgets.QDialogButtonBox(self)
self.dialog_button_box.addButton(self.button,
QtWidgets.QDialogButtonBox.RejectRole)
self.progress_bar = QtWidgets.QProgressBar(self)
self.progress_bar.setValue(0)
self.progress_bar.hide()
self.bottom_layout.addWidget(self.progress_bar)
self.bottom_layout.addWidget(self.dialog_button_box)
self.layout.addLayout(self.bottom_layout)
#: Running job indicator.
self.running = False
self.max_position = True
self.vertical_scrollbar = self.text_edit.verticalScrollBar()
self.vertical_scrollbar.sliderMoved.connect(self.sliderValueChanged)
[docs] def sliderValueChanged(self, new_value):
if new_value >= self.vertical_scrollbar.maximum():
self.max_position = True
else:
self.max_position = False
[docs] def hide(self):
self.updateProgress()
QtWidgets.QDialog.hide(self)
[docs] def setButtonText(self, text):
"""
Sets push button text. The default text is "Cancel".
:type text: str
:param text: Push button text label.
"""
self.button.setText(text)
[docs] def setText(self, text):
"""
Sets text contents of the dialog. This is usually set to job output.
:type text: str
:param text: Text to be displayed in the dialog.
"""
if text == self.text_document.toPlainText():
return
h_position = self.text_edit.horizontalScrollBar().value()
position = self.vertical_scrollbar.value()
self.text_document.setPlainText(text)
self.text_edit.setDocument(self.text_document)
self.refresh()
if self.max_position:
cursor = self.text_edit.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
self.text_edit.setTextCursor(cursor)
self.max_position = True
else:
self.vertical_scrollbar.setValue(position)
self.max_position = False
self.text_edit.horizontalScrollBar().setValue(h_position)
self.refresh()
[docs] def appendText(self, text):
"""
Appends new text to the dialog.
:type text: str
:param text: Text to be appended to the dialog text.
"""
old_text = str(self.text_document.toPlainText())
if text == old_text:
return
h_position = self.text_edit.horizontalScrollBar().value()
position = self.vertical_scrollbar.value()
self.text_document.setPlainText(old_text + text)
self.text_edit.setDocument(self.text_document)
self.refresh()
if self.max_position:
cursor = self.text_edit.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
self.text_edit.setTextCursor(cursor)
self.max_position = True
else:
self.vertical_scrollbar.setValue(position)
self.max_position = False
self.text_edit.horizontalScrollBar().setValue(h_position)
self.refresh()
[docs] def refresh(self):
"""
Refreshes the dialog contents by processing pending Qt events.
"""
self.text_edit.repaint()
QtCore.QCoreApplication.processEvents()
[docs] def isRunning(self):
return self.running
[docs] def startJob(self):
self.updateProgress()
self.show()
self.raise_()
self.activateWindow()
self.running = True
[docs] def endJob(self, hide=True):
self.running = False
self.setButtonText("Close")
if hide:
self.hide()
[docs] def updateProgress(self, progress=None):
if progress is not None:
self.progress_bar.show()
self.progress_bar.setValue(int(100.0 * progress))
else:
self.progress_bar.hide()
self.update()
[docs]def createJobProgressDialog(title, parent=None):
"""
Creates a job progress dialog.
:type title: str
:param title: Dialog title.
:rtype: `JobProgressDialog`
:return: Created dialog.
"""
global _JOB_PROGRESS_DIALOGS_BY_PARENT
if parent not in _JOB_PROGRESS_DIALOGS_BY_PARENT:
dialog = JobProgressDialog(parent=parent)
dialog.setMinimumSize(500, 300)
_JOB_PROGRESS_DIALOGS_BY_PARENT[parent] = dialog
else:
dialog = _JOB_PROGRESS_DIALOGS_BY_PARENT[parent]
if title:
dialog.setWindowTitle(title)
return dialog
[docs]class ConfigDialogMSV(ConfigDialog):
""" MSV variant of the job configuration dialog """
[docs] def __init__(self, parent, **kw):
ConfigDialog.__init__(self,
parent,
jobname='msv',
title='Multiple Sequence Viewer Job Settings',
jobentry=False,
tmpdir=True,
cpus=True)
self.main_layout.removeWidget(self.button_box)
self.files_group = QtWidgets.QGroupBox("File location", self.dialog)
self.files_layout = QtWidgets.QVBoxLayout(self.files_group)
self.files_layout.setContentsMargins(3, -1, 3, 3)
self.files_layout.setSpacing(1)
self.location_layout = QtWidgets.QHBoxLayout()
self.files_layout.addLayout(self.location_layout)
self.main_layout.addWidget(self.files_group)
self.tmp_rb = QtWidgets.QRadioButton("Temporary directory", self.dialog)
self.tmp_rb.setChecked(True)
self.location_layout.addWidget(self.tmp_rb)
self.cwd_rb = QtWidgets.QRadioButton("Current directory", self.dialog)
self.location_layout.addWidget(self.cwd_rb)
self.keep_files_cb = QtWidgets.QCheckBox("Keep temporary job files",
self.dialog)
self.files_layout.addWidget(self.keep_files_cb)
self.main_layout.addWidget(self.button_box)
[docs]def createJobSettingsDialog(parent=None):
global _JOB_SETTINGS_DIALOGS_BY_PARENT
if parent not in _JOB_SETTINGS_DIALOGS_BY_PARENT:
dialog = ConfigDialogMSV(parent=parent)
_JOB_SETTINGS_DIALOGS_BY_PARENT[parent] = dialog
else:
dialog = _JOB_SETTINGS_DIALOGS_BY_PARENT[parent]
result = dialog.activate()
cmd_line = ""
if result:
cmd_line = result.commandLineArgs()
settings = {}
settings["command_line"] = cmd_line
settings["temporary_dir"] = dialog.tmp_rb.isChecked()
settings["keep_files"] = dialog.keep_files_cb.isChecked()
return settings