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