예제 #1
0
파일: tool.py 프로젝트: dials/cctbx
    def __init__(self, session, tool_name):
        # 'session'   - chimerax.core.session.Session instance
        # 'tool_name' - string

        # Initialize base class.
        super().__init__(session, tool_name)

        # Set name displayed on title bar (defaults to tool_name)
        # Must be after the superclass init, which would override it.
        self.display_name = "HKLviewer"
        # Create the main window for our tool.  The window object will have
        # a 'ui_area' where we place the widgets composing our interface.
        # The window isn't shown until we call its 'manage' method.
        #
        # Note that by default, tool windows are only hidden rather than
        # destroyed when the user clicks the window's close button.  To change
        # this behavior, specify 'close_destroys=True' in the MainToolWindow
        # constructor.
        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        # We will be adding an item to the tool's context menu, so override
        # the default MainToolWindow fill_context_menu method
        self.tool_window.fill_context_menu = self.fill_context_menu

        # Our user interface is simple enough that we could probably inline
        # the code right here, but for any kind of even moderately complex
        # interface, it is probably better to put the code in a method so
        # that this __init__ method remains readable.
        self._build_ui()
        self.clipper_crystdict = None
        session.HKLviewer = self
예제 #2
0
    def __init__(self, session, tool_name, *, title=None):
        ToolInstance.__init__(self, session, tool_name)

        from chimerax.ui import MainToolWindow
        tw = MainToolWindow(self)
        if title is not None:
            tw.title = title
        self.tool_window = tw
        parent = tw.ui_area

        from matplotlib import figure
        self.figure = f = figure.Figure(dpi=100, figsize=(2, 2))

        from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
        self.canvas = c = Canvas(f)
        parent.setMinimumHeight(
            1
        )  # Matplotlib gives divide by zero error when plot resized to 0 height.
        c.setParent(parent)

        from PyQt5.QtWidgets import QHBoxLayout
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(c)
        parent.setLayout(layout)
        tw.manage(placement="side")

        self.axes = axes = f.gca()

        self._pan = None  # Pan/zoom mouse control
예제 #3
0
    def __init__(self, session):
        ToolInstance.__init__(self, session, "Bogus Toolshed-demo Tool")

        self.display_name = "Open Models"
        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self, size=self.SIZE)
        parent = self.tool_window.ui_area
        # UI content code
        from wx import html2
        import wx
        self.webview = html2.WebView.New(parent, wx.ID_ANY, size=self.SIZE)
        self.webview.Bind(html2.EVT_WEBVIEW_NAVIGATING,
                          self._on_navigating,
                          id=self.webview.GetId())
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.webview, 1, wx.EXPAND)
        parent.SetSizerAndFit(sizer)
        self.tool_window.manage(placement="side")
        # Add triggers for model addition/removal
        from chimerax.core.models import ADD_MODELS, REMOVE_MODELS
        self._handlers = [
            session.triggers.add_handler(ADD_MODELS, self._make_page),
            session.triggers.add_handler(REMOVE_MODELS, self._make_page)
        ]
        self._make_page()
예제 #4
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)
        # 'display_name' defaults to class name with spaces inserted
        # between lower-then-upper-case characters (therefore "Tool UI"
        # in this case), so only override if different name desired
        self.display_name = "ChimeraX Python Shell"
        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)
        parent = self.tool_window.ui_area
        # UI content code
        from ipykernel.ipkernel import IPythonKernel
        save_ns = IPythonKernel.user_ns
        IPythonKernel.user_ns = {'session': session}
        from qtconsole.inprocess import QtInProcessKernelManager
        kernel_manager = QtInProcessKernelManager()
        kernel_manager.start_kernel()
        kernel_client = kernel_manager.client()
        kernel_client.start_channels()

        from qtconsole.rich_jupyter_widget import RichJupyterWidget
        self.shell = RichJupyterWidget(parent)
        def_banner = self.shell.banner
        self.shell.banner = "{}\nCurrent ChimeraX session available as 'session'.\n\n".format(
            def_banner)
        self.shell.kernel_manager = kernel_manager
        self.shell.kernel_client = kernel_client
        IPythonKernel.user_ns = save_ns

        from PyQt5.QtWidgets import QHBoxLayout
        layout = QHBoxLayout()
        layout.addWidget(self.shell)
        layout.setStretchFactor(self.shell, 1)
        parent.setLayout(layout)
        self.tool_window.manage(placement=None)
예제 #5
0
    def __init__(self, session, name):
        super().__init__(session, name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        self.settings = _SterimolSettings(self.session, name)

        self._build_ui()
예제 #6
0
파일: libadd.py 프로젝트: QChASM/SEQCROW
    def __init__(self, session, name):
        super().__init__(session, name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        self.key_atomspec = []

        self._build_ui()
예제 #7
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self, close_destroys=False)
        parent = self.tool_window.ui_area

        from chimerax.ui.file_history import FileHistory
        fh = FileHistory(session, parent, size_hint=(575, 200))
        self.tool_window.manage(placement="side")
예제 #8
0
    def __init__(self, session, name):
        super().__init__(session, name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        self.settings = _ConeAngleSettings(self.session, name)

        self.ligands = dict()

        self._build_ui()
예제 #9
0
    def __init__(self, session, tool_name):
        super().__init__(session, tool_name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        self._build_ui()
        from chimerax.core.models import ADD_MODELS, REMOVE_MODELS
        session.triggers.add_handler(ADD_MODELS, self._fill_ui)
        session.triggers.add_handler(REMOVE_MODELS, self._fill_ui)
        self._fill_ui()
예제 #10
0
 def __init__(self, session, tool_name):
     super().__init__(session, tool_name)
     self.display_name = "Toolbar"
     global _settings
     if _settings is None:
         _settings = _ToolbarSettings(self.session, "Toolbar")
     from chimerax.ui import MainToolWindow
     self.tool_window = MainToolWindow(self, close_destroys=False, hide_title_bar=True)
     self._build_ui()
     self.tool_window.fill_context_menu = self.fill_context_menu
     session.triggers.add_handler('set right mouse', self._set_right_mouse_button)
예제 #11
0
    def __init__(self, session, tool_name):

        self._requested_halt = False
        self._model_move_handler = None
        self._last_relative_position = None

        self.max_steps = 2000
        self.ijk_step_size_min = 0.01
        self.ijk_step_size_max = 0.5
        self._last_status_time = 0
        self._status_interval = 0.5  # seconds

        ToolInstance.__init__(self, session, tool_name)

        from chimerax.ui import MainToolWindow
        tw = MainToolWindow(self)
        self.tool_window = tw
        parent = tw.ui_area

        from PyQt5.QtWidgets import QVBoxLayout, QLabel
        layout = QVBoxLayout(parent)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        parent.setLayout(layout)

        # Make menus to choose molecule and map for fitting
        mf = self._create_mol_map_menu(parent)
        layout.addWidget(mf)

        # Report correlation
        from chimerax.ui.widgets import EntriesRow
        cr = EntriesRow(
            parent, 'Correlation', 0.0, 'Average map value', 0.0,
            ('Update',
             lambda *args, self=self: self._update_metric_values(log=True)))
        self._corr_label, self._ave_label = cl, al = cr.values
        cl.value = al.value = None  # Make fields blank

        # Options panel
        options = self._create_options_gui(parent)
        layout.addWidget(options)

        # Fit, Undo, Redo buttons
        bf = self._create_action_buttons(parent)
        layout.addWidget(bf)

        # Status line
        self._status_label = sl = QLabel(parent)
        layout.addWidget(sl)

        layout.addStretch(1)  # Extra space at end

        tw.manage(placement="side")
예제 #12
0
 def create_button_panel(self):
     from chimerax.ui import MainToolWindow
     tw = MainToolWindow(self, close_destroys=False)
     self.tool_window = tw
     p = tw.ui_area
     from PyQt5.QtWidgets import QVBoxLayout
     layout = QVBoxLayout(p)
     layout.setContentsMargins(0, 0, 0, 0)
     layout.setSpacing(0)
     b = self.create_panel_buttons(p)
     p.setLayout(layout)
     layout.addWidget(b)
     tw.manage(placement="side")
예제 #13
0
    def __init__(self, session, name):
        super().__init__(session, name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        self.settings = _BrowseLibSettings(self.session, name)

        self.showLigKeyBool = True
        self.showSubGhostBool = True
        self.showRingWalkBool = True

        self._build_ui()
예제 #14
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)
        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)
        parent = self.tool_window.ui_area

        # UI content code
        from PyQt5.QtCore import Qt
        from PyQt5.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QCheckBox, QStackedWidget
        self.view = v = View(session.models.scene_root_model, window_size=(0, 0))
        v.initialize_rendering(session.main_view.render.opengl_context)
        # TODO: from chimerax.graphics.camera import OrthographicCamera
        v.camera = OrthoCamera()
        if self.display_name.startswith('Top'):
            side = SideViewCanvas.TOP_SIDE
        else:
            side = SideViewCanvas.RIGHT_SIDE
        self.opengl_canvas = SideViewCanvas(parent, v, session, self, side=side)
        clip = QLabel(parent)
        clip.setText("clip:")
        self.clip_near = QCheckBox(parent)
        self.clip_near.setText("near")
        self.clip_near.down = False
        # TODO: parent.Bind(wx.EVT_CHECKBOX, self.on_near, self.clip_near)
        self.clip_near.clicked.connect(self.on_near)
        self.clip_far = QCheckBox(parent)
        self.clip_far.setText("far")
        self.clip_far.down = False
        # TODO: parent.Bind(wx.EVT_CHECKBOX, self.on_far, self.clip_far)
        self.clip_far.clicked.connect(self.on_far)

        button_layout = QHBoxLayout()
        button_layout.addWidget(clip, alignment=Qt.AlignCenter)
        button_layout.addWidget(self.clip_near)
        button_layout.addWidget(self.clip_far)
        button_layout.addStretch(1)

        class graphics_area(QStackedWidget):

            def sizeHint(self):  # noqa
                from PyQt5.QtCore import QSize
                return QSize(200, 200)

        layout = QVBoxLayout()
        ga = graphics_area(parent)
        ga.addWidget(self.opengl_canvas.widget)
        layout.addWidget(ga, 1)
        layout.addLayout(button_layout)
        parent.setLayout(layout)
        self.tool_window.manage(placement="side")
예제 #15
0
class FilePanel(ToolInstance):

    SESSION_ENDURING = True
    help = "help:user/tools/filehistory.html"

    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self, close_destroys=False)
        parent = self.tool_window.ui_area

        from chimerax.ui.file_history import FileHistory
        fh = FileHistory(session, parent, size_hint=(575, 200))
        self.tool_window.manage(placement="side")
예제 #16
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)
        from chimerax.ui import MainToolWindow
        self.tool_window = tw = MainToolWindow(self)
        parent = tw.ui_area
        from PyQt5.QtWidgets import QVBoxLayout, QDialogButtonBox
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        parent.setLayout(layout)
        from .gui import HBondsGUI
        self.gui = HBondsGUI(session, show_model_restrict=False)
        layout.addWidget(self.gui)

        from PyQt5.QtWidgets import QDialogButtonBox as qbbox
        bbox = qbbox(qbbox.Ok | qbbox.Apply | qbbox.Close | qbbox.Help)
        bbox.accepted.connect(self.run_hbonds)
        bbox.button(qbbox.Apply).clicked.connect(self.run_hbonds)
        bbox.accepted.connect(
            self.delete)  # slots executed in the order they are connected
        bbox.rejected.connect(self.delete)
        from chimerax.core.commands import run
        bbox.helpRequested.connect(
            lambda run=run, ses=session: run(ses, "help " + self.help))
        layout.addWidget(bbox)

        tw.manage(placement=None)
예제 #17
0
    def __init__(self, gui_class, help_url, *args, **kw):
        super().__init__(*args, **kw)
        self.help = help_url

        from chimerax.ui import MainToolWindow
        self.tool_window = tw = MainToolWindow(self)
        parent = tw.ui_area
        from PyQt5.QtWidgets import QVBoxLayout, QDialogButtonBox
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        parent.setLayout(layout)
        self.gui = gui_class(self.session, has_apply_button=True)
        layout.addWidget(self.gui)

        from PyQt5.QtWidgets import QDialogButtonBox as qbbox
        bbox = qbbox(qbbox.Ok | qbbox.Apply | qbbox.Close | qbbox.Help)
        bbox.accepted.connect(self.run_command)
        bbox.button(qbbox.Apply).clicked.connect(self.run_command)
        bbox.accepted.connect(
            self.delete)  # slots executed in the order they are connected
        bbox.rejected.connect(self.delete)
        if self.help:
            from chimerax.core.commands import run
            bbox.helpRequested.connect(lambda run=run, ses=self.session: run(
                ses, "help " + self.help))
        else:
            bbox.button(qbbox.Help).setEnabled(False)
        layout.addWidget(bbox)

        tw.manage(placement=None)
예제 #18
0
    def __init__(self, session, title):
        ToolInstance.__init__(self, session, title)

        self.title = title
        self._rows = None
        self._columns = None
        self._next_row_col = (1, 1)
        self._fill_order = 'rows'
        self._buttons = {}  # Map (row,column) -> QPushButton

        from chimerax.ui import MainToolWindow
        tw = MainToolWindow(self)
        self.tool_window = tw
        from PyQt5.QtWidgets import QGridLayout
        self._layout = layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        tw.ui_area.setLayout(layout)
        tw.manage(placement="side")
예제 #19
0
  def __init__(self, session, tool_name):

    ToolInstance.__init__(self, session, tool_name)

    from chimerax.ui import MainToolWindow
    tw = MainToolWindow(self)
    self.tool_window = tw
    parent = tw.ui_area

    from PyQt5.QtWidgets import QVBoxLayout, QLabel
    layout = QVBoxLayout(parent)
    layout.setContentsMargins(0,0,0,0)
    layout.setSpacing(0)
    parent.setLayout(layout)

    # Heading
    heading = QLabel('Placement of data array in x,y,z coordinate space:', parent)
    layout.addWidget(heading)
    
    # Make menus to choose molecule and map for fitting
    mf = self._create_map_menu(parent)
    layout.addWidget(mf)

    # GUI for origin, step, angles, axis settings.
    options = self._create_parameters_gui(parent)
    layout.addWidget(options)

    # Apply button
#    bf = self._create_action_buttons(parent)
#    layout.addWidget(bf)
  
    # Status line
    self._status_label = sl = QLabel(parent)
    layout.addWidget(sl)
        
    layout.addStretch(1)    # Extra space at end

    self._update_gui_values()

    tw.manage(placement="side")
예제 #20
0
    def _finalize_init(self,
                       session,
                       models,
                       attr_names,
                       scores_fetched=False):
        self.models = models
        self.attr_names = attr_names
        from chimerax.core.models import REMOVE_MODELS
        self.handlers = [
            session.triggers.add_handler(REMOVE_MODELS,
                                         self._models_removed_cb)
        ]

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self,
                                          close_destroys=False,
                                          statusbar=False)
        self.tool_window.fill_context_menu = self.fill_context_menu
        parent = self.tool_window.ui_area

        from PyQt5.QtWidgets import QTableWidget, QVBoxLayout, QAbstractItemView, QWidget, QPushButton
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        parent.setLayout(layout)
        self.table = QTableWidget()
        self.table.setSortingEnabled(True)
        self.table.keyPressEvent = session.ui.forward_keystroke
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.table.itemSelectionChanged.connect(self._table_selection_cb)
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        layout.addWidget(self.table)
        layout.setStretchFactor(self.table, 1)
        self._fill_table()
        self.tool_window.manage('side')
        self.scores_fetched = scores_fetched
        for m in models:
            self.handlers.append(
                m.triggers.add_handler("changes", self._changes_cb))
예제 #21
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)

        self.minimize_steps = 10
        self.edge_thickness = 0.1  # Edge diameter as fraction of edge length.

        self.display_name = 'Cage Builder'

        from chimerax.ui import MainToolWindow
        tw = MainToolWindow(self)
        self.tool_window = tw
        parent = tw.ui_area

        from PyQt5.QtWidgets import QHBoxLayout, QLabel, QPushButton, QLineEdit
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        cp = QLabel('Create polygon')
        layout.addWidget(cp)
        b5 = QPushButton('5')
        b5.clicked.connect(lambda e: self.attach_polygons(5))
        layout.addWidget(b5)
        b6 = QPushButton('6')
        b6.clicked.connect(lambda e: self.attach_polygons(6))
        layout.addWidget(b6)
        mn = QPushButton('Minimize')
        mn.clicked.connect(self.minimize_cb)
        layout.addWidget(mn)
        ell = QLabel(' Edge length')
        layout.addWidget(ell)
        self.edge_length = el = QLineEdit('50')
        el.setMaximumWidth(30)
        layout.addWidget(el)
        dp = QPushButton('Delete')
        dp.clicked.connect(self.delete_polygon_cb)
        layout.addWidget(dp)
        layout.addStretch(1)  # Extra space at end of button row.
        parent.setLayout(layout)

        tw.manage(placement="side")
예제 #22
0
    def __init__(self, session, tool_name):
        # Standard template stuff
        ToolInstance.__init__(self, session, tool_name)
        self.display_name = "Toolshed"
        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)
        self.tool_window.manage(placement=None)
        parent = self.tool_window.ui_area

        from PyQt5.QtWidgets import QGridLayout, QTabWidget
        from chimerax.ui.widgets import HtmlView
        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.tab_widget = QTabWidget()
        self.html_view = HtmlView(size_hint=(1000, 600),
                                  download=self._download)
        self.tab_widget.addTab(self.html_view, "Toolshed")
        layout.addWidget(self.tab_widget, 0, 0)
        parent.setLayout(layout)

        from PyQt5.QtCore import QUrl
        self.html_view.setUrl(QUrl(self.url))
        self._pending_downloads = []
예제 #23
0
    def __init__(self, session, model, filereader):
        super().__init__(session, model.name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        self.structure = model
        self.filereader = filereader

        self.display_name = "Thing per iteration for %s" % model.name

        self._last_mouse_xy = None
        self._dragged = False
        self._min_drag = 10  # pixels
        self._drag_mode = None

        self._build_ui()

        self.press = None
        self.drag_prev = None
        self.dragging = False

        self._model_closed = self.session.triggers.add_handler(
            REMOVE_MODELS, self.check_closed_models)
예제 #24
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)
        self.display_name = "Show Chain Sequence"
        self.settings = SequencesSettings(session, "ChainSequences")

        from chimerax.ui import MainToolWindow
        self.tool_window = tw = MainToolWindow(self)
        parent = tw.ui_area

        from PyQt5.QtWidgets import QVBoxLayout, QCheckBox
        layout = QVBoxLayout()
        parent.setLayout(layout)
        from chimerax.atomic.widgets import ChainListWidget
        self.chain_list = ChainListWidget(session, group_identical=self.settings.grouping,
            autoselect="first")
        self.chain_list.value_changed.connect(self._update_show_button)
        layout.addWidget(self.chain_list, stretch=1)

        self.grouping_button = QCheckBox("Group identical sequences")
        self.grouping_button.setChecked(self.settings.grouping)
        self.grouping_button.stateChanged.connect(self._grouping_change)
        layout.addWidget(self.grouping_button)

        from PyQt5.QtWidgets import QDialogButtonBox as qbbox
        bbox = qbbox()
        self._show_button = bbox.addButton("Show", qbbox.AcceptRole)
        bbox.addButton(qbbox.Cancel)
        #bbox.addButton(qbbox.Help)
        bbox.accepted.connect(self.show_seqs)
        bbox.accepted.connect(self.delete) # slots executed in the order they are connected
        bbox.rejected.connect(self.delete)
        from chimerax.core.commands import run
        bbox.helpRequested.connect(lambda run=run, ses=session: run(ses, "help " + self.help))
        layout.addWidget(bbox)

        self._update_show_button()

        tw.manage(placement=None)
예제 #25
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)
        from chimerax.ui import MainToolWindow
        self.tool_window = tw = MainToolWindow(self)
        parent = tw.ui_area
        layout = QVBoxLayout()
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(3)
        parent.setLayout(layout)

        session.logger.status("Build Structure is a work in progress, more functions coming soon...",
            color="blue")

        self.category_button = QPushButton()
        layout.addWidget(self.category_button, alignment=Qt.AlignCenter)
        cat_menu = QMenu(parent)
        self.category_button.setMenu(cat_menu)
        cat_menu.triggered.connect(self._cat_menu_cb)

        self.category_areas = QStackedWidget()
        layout.addWidget(self.category_areas)

        self.handlers = []
        self.category_widgets = {}
        for category in ["Start Structure", "Modify Structure"]:
            self.category_widgets[category] = widget = QFrame()
            widget.setLineWidth(2)
            widget.setFrameStyle(QFrame.Panel | QFrame.Sunken)
            getattr(self, "_layout_" + category.lower().replace(' ', '_'))(widget)
            self.category_areas.addWidget(widget)
            cat_menu.addAction(category)
        initial_category = "Start Structure"
        self.category_button.setText(initial_category)
        self.category_areas.setCurrentWidget(self.category_widgets[initial_category])

        tw.manage(placement="side")
예제 #26
0
    def __init__(self, session, tool_name):
        ToolInstance.__init__(self, session, tool_name)
        self.display_name = "Models"
        self.settings = ModelPanelSettings(session, "ModelPanel")
        last = self.settings.last_use
        from time import time
        now = self.settings.last_use = time()
        short_titles = last != None and now - last < 777700 # about 3 months

        from chimerax.ui import MainToolWindow
        self.tool_window = tw = MainToolWindow(self, close_destroys=False)
        parent = tw.ui_area
        from PyQt5.QtWidgets import QTreeWidget, QHBoxLayout, QVBoxLayout, QAbstractItemView, \
            QFrame, QPushButton, QSizePolicy
        class SizedTreeWidget(QTreeWidget):
            def sizeHint(self):
                from PyQt5.QtCore import QSize
                # side buttons will keep the vertical size reasonable
                if getattr(self, '_first_size_hint_call', True):
                    self._first_size_hint_call = False
                    width = 0
                else:
                    width = self.header().length()
                return QSize(width, 200)
        self.tree = SizedTreeWidget()
        self.tree.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.tree.keyPressEvent = session.ui.forward_keystroke
        self.tree.expanded.connect(self._ensure_id_width)
        layout = QHBoxLayout()
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(0)
        layout.addWidget(self.tree)
        layout.setStretchFactor(self.tree, 1)
        parent.setLayout(layout)
        shown_title = "" if short_titles else "Shown"
        sel_title = "" if short_titles else "Select"
        self.tree.setHeaderLabels(["Name", "ID", " ", shown_title, sel_title])
        from chimerax.ui.icons import get_qt_icon
        self.tree.headerItem().setIcon(3, get_qt_icon("shown"))
        self.tree.headerItem().setToolTip(3, "Shown")
        self.tree.headerItem().setIcon(4, get_qt_icon("select"))
        self.tree.headerItem().setToolTip(4, "Selected")
        self.tree.setColumnWidth(self.NAME_COLUMN, 200)
        self.tree.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tree.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.tree.setAnimated(True)
        self.tree.setUniformRowHeights(True)
        self.tree.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tree.itemChanged.connect(self._tree_change_cb)
        buttons_layout = QVBoxLayout()
        layout.addLayout(buttons_layout)
        self._items = []
        for model_func in [close, hide, show, view]:
            button = QPushButton(model_func.__name__.capitalize())
            buttons_layout.addWidget(button)
            button.clicked.connect(lambda chk, self=self, mf=model_func, ses=session:
                mf([self.models[row] for row in [self._items.index(i)
                    for i in self.tree.selectedItems()]] or self.models, ses))
        self.simply_changed_models = set()
        self.check_model_list = True
        self.countdown = 1
        self.self_initiated = False
        from chimerax.core.models import ADD_MODELS, REMOVE_MODELS, \
            MODEL_DISPLAY_CHANGED, MODEL_ID_CHANGED, MODEL_NAME_CHANGED
        from chimerax.core.selection import SELECTION_CHANGED
        session.triggers.add_handler(SELECTION_CHANGED,
            lambda *args: self._initiate_fill_tree(*args, countdown=3))
        session.triggers.add_handler(MODEL_DISPLAY_CHANGED,
            lambda *args: self._initiate_fill_tree(*args, simple_change=True, countdown=(0,3)))
        session.triggers.add_handler(ADD_MODELS,
            lambda *args: self._initiate_fill_tree(*args, always_rebuild=True, countdown=(3,10)))
        session.triggers.add_handler(REMOVE_MODELS,
            lambda *args: self._initiate_fill_tree(*args, always_rebuild=True))
        session.triggers.add_handler(MODEL_ID_CHANGED,
            lambda *args: self._initiate_fill_tree(*args, always_rebuild=True, countdown=3))
        session.triggers.add_handler(MODEL_NAME_CHANGED,
            lambda *args: self._initiate_fill_tree(*args, simple_change=True, countdown=3))
        from chimerax import atomic
        atomic.get_triggers().add_handler("changes", self._changes_cb)
        self._frame_drawn_handler = None
        tw.manage(placement="side")
        tw.shown_changed = self._shown_changed
예제 #27
0
파일: tool.py 프로젝트: dials/cctbx
class HKLviewerTool(ToolInstance):

    # Inheriting from ToolInstance makes us known to the ChimeraX tool mangager,
    # so we can be notified and take appropriate action when sessions are closed,
    # saved, or restored, and we will be listed among running tools and so on.
    #
    # If cleaning up is needed on finish, override the 'delete' method
    # but be sure to call 'delete' from the superclass at the end.
    SESSION_ENDURING = False    # Does this instance persist when session closes
    SESSION_SAVE = True         # We do save/restore in sessions
    help = "help:user/tools/tutorial.html"
                                # Let ChimeraX know about our help page


    def __init__(self, session, tool_name):
        # 'session'   - chimerax.core.session.Session instance
        # 'tool_name' - string

        # Initialize base class.
        super().__init__(session, tool_name)

        # Set name displayed on title bar (defaults to tool_name)
        # Must be after the superclass init, which would override it.
        self.display_name = "HKLviewer"
        # Create the main window for our tool.  The window object will have
        # a 'ui_area' where we place the widgets composing our interface.
        # The window isn't shown until we call its 'manage' method.
        #
        # Note that by default, tool windows are only hidden rather than
        # destroyed when the user clicks the window's close button.  To change
        # this behavior, specify 'close_destroys=True' in the MainToolWindow
        # constructor.
        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        # We will be adding an item to the tool's context menu, so override
        # the default MainToolWindow fill_context_menu method
        self.tool_window.fill_context_menu = self.fill_context_menu

        # Our user interface is simple enough that we could probably inline
        # the code right here, but for any kind of even moderately complex
        # interface, it is probably better to put the code in a method so
        # that this __init__ method remains readable.
        self._build_ui()
        self.clipper_crystdict = None
        session.HKLviewer = self

    def _build_ui(self):
        # Put our widgets in the tool window

        # We will use an editable single-line text input field (QLineEdit)
        # with a descriptive text label to the left of it (QLabel).  To
        # arrange them horizontally side by side we use QHBoxLayout
        from Qt.QtWidgets import QHBoxLayout
        from . import HKLviewer

        hbox = QHBoxLayout()
        self.Guiobj = HKLviewer.run(isembedded=True, chimeraxsession=self.session)
        hbox.addWidget(self.Guiobj.window)
        self.tool_window.ui_area.setLayout(hbox)
        # Show the window on the user-preferred side of the ChimeraX
        # main window
        self.tool_window.manage('side')

    def isolde_clipper_data_to_dict(self):
        try:
            sh = self.session.isolde.selected_model.parent
            xmapset = sh.map_mgr.xmapsets[0]
            clipperlabel= list(xmapset.experimental_data.items())[0][0]
            labels = [lbl.strip() for lbl in clipperlabel.split(",")]
            self.clipper_crystdict = {}
            self.clipper_crystdict["spg_number"] = xmapset.spacegroup.spacegroup_number
            self.clipper_crystdict["unit_cell"] =  (xmapset.unit_cell.cell.a, xmapset.unit_cell.cell.b, xmapset.unit_cell.cell.c,
               xmapset.unit_cell.cell.alpha*180/math.pi, xmapset.unit_cell.cell.beta*180/math.pi, xmapset.unit_cell.cell.gamma*180/math.pi)
            self.clipper_crystdict["HKL"] = xmapset.experimental_data[clipperlabel].data.data[0].tolist()
            self.clipper_crystdict[clipperlabel] = xmapset.experimental_data[clipperlabel].data.data[1].transpose().tolist()
            self.clipper_crystdict["FCALC,PHFCALC"] = xmapset.live_xmap_mgr.f_calc.data[1].transpose().tolist()
            self.clipper_crystdict["2FOFC,PH2FOFC"] = xmapset.live_xmap_mgr.base_2fofc.data[1].transpose().tolist()
        except Exception as e:
            pass


    def return_pressed(self):
        # The use has pressed the Return key; log the current text as HTML
        from chimerax.core.commands import run
        # ToolInstance has a 'session' attribute...
        run(self.session, "log html %s" % self.line_edit.text())

    def fill_context_menu(self, menu, x, y):
        # Add any tool-specific items to the given context menu (a QMenu instance).
        # The menu will then be automatically filled out with generic tool-related actions
        # (e.g. Hide Tool, Help, Dockable Tool, etc.)
        #
        # The x,y args are the x() and y() values of QContextMenuEvent, in the rare case
        # where the items put in the menu depends on where in the tool interface the menu
        # was raised.
        from PyQt5.QtWidgets import QAction
        settings_action = QAction("HKLviewer settings", menu)
        settings_action.triggered.connect(lambda *args: self.Guiobj.SettingsDialog() )
        menu.addAction(settings_action)

    def delete(self):
      from Qt.QtCore import QEvent
      self.session.triggers.remove_handler(self.Guiobj.chimeraxprocmsghandler)
      self.Guiobj.closeEvent(QEvent.Close)
      super(HKLviewerTool, self).delete()

    def take_snapshot(self, session, flags):
        return {
            'version': 1,
            'current text': self.line_edit.text()
        }

    @classmethod
    def restore_snapshot(class_obj, session, data):
        # Instead of using a fixed string when calling the constructor below, we could
        # have saved the tool name during take_snapshot() (from self.tool_name, inherited
        # from ToolInstance) and used that saved tool name.  There are pros and cons to
        # both approaches.
        inst = class_obj(session, "cctbx.HKLviewer")
        inst.line_edit.setText(data['current text'])
        return inst
예제 #28
0
class ConeAngle(ToolInstance):

    help = "https://github.com/QChASM/SEQCROW/wiki/Cone-Angle-Tool"

    def __init__(self, session, name):
        super().__init__(session, name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        self.settings = _ConeAngleSettings(self.session, name)

        self.ligands = dict()

        self._build_ui()

    def _build_ui(self):
        layout = QFormLayout()

        self.cone_option = QComboBox()
        self.cone_option.addItems(["Tolman (Unsymmetrical)", "Exact"])
        ndx = self.cone_option.findText(self.settings.cone_option,
                                        Qt.MatchExactly)
        self.cone_option.setCurrentIndex(ndx)
        layout.addRow("method:", self.cone_option)

        self.radii_option = QComboBox()
        self.radii_option.addItems(["Bondi", "UMN"])
        ndx = self.radii_option.findText(self.settings.radii, Qt.MatchExactly)
        self.radii_option.setCurrentIndex(ndx)
        layout.addRow("radii:", self.radii_option)

        self.display_cone = QCheckBox()
        self.display_cone.setChecked(self.settings.display_cone)
        layout.addRow("show cone:", self.display_cone)

        self.display_radii = QCheckBox()
        self.display_radii.setChecked(self.settings.display_radii)
        layout.addRow("show radii:", self.display_radii)

        set_ligand_button = QPushButton("set ligand to current selection")
        set_ligand_button.clicked.connect(self.set_ligand)
        layout.addRow(set_ligand_button)
        self.set_ligand_button = set_ligand_button

        calc_cone_button = QPushButton(
            "calculate cone angle for ligand on selected center")
        calc_cone_button.clicked.connect(self.calc_cone)
        layout.addRow(calc_cone_button)
        self.calc_cone_button = calc_cone_button

        remove_cone_button = QPushButton("remove cone visualizations")
        remove_cone_button.clicked.connect(self.del_cone)
        layout.addRow(remove_cone_button)
        self.remove_cone_button = remove_cone_button

        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels([
            'model',
            'center',
            'cone angle (°)',
        ])

        self.table.setSelectionBehavior(QTableWidget.SelectRows)
        self.table.setEditTriggers(QTableWidget.NoEditTriggers)
        self.table.resizeColumnToContents(0)
        self.table.resizeColumnToContents(1)
        self.table.resizeColumnToContents(2)
        self.table.horizontalHeader().setSectionResizeMode(
            2, QHeaderView.Stretch)
        layout.addRow(self.table)

        menu = QMenuBar()

        export = menu.addMenu("&Export")

        clear = QAction("Clear data table", self.tool_window.ui_area)
        clear.triggered.connect(self.clear_table)
        export.addAction(clear)

        copy = QAction("&Copy CSV to clipboard", self.tool_window.ui_area)
        copy.triggered.connect(self.copy_csv)
        shortcut = QKeySequence(Qt.CTRL + Qt.Key_C)
        copy.setShortcut(shortcut)
        export.addAction(copy)

        save = QAction("&Save CSV...", self.tool_window.ui_area)
        save.triggered.connect(self.save_csv)
        #this shortcut interferes with main window's save shortcut
        #I've tried different shortcut contexts to no avail
        #thanks Qt...
        #shortcut = QKeySequence(Qt.CTRL + Qt.Key_S)
        #save.setShortcut(shortcut)
        #save.setShortcutContext(Qt.WidgetShortcut)
        export.addAction(save)

        delimiter = export.addMenu("Delimiter")

        comma = QAction("comma", self.tool_window.ui_area, checkable=True)
        comma.setChecked(self.settings.delimiter == "comma")
        comma.triggered.connect(lambda *args, delim="comma": self.settings.
                                __setattr__("delimiter", delim))
        delimiter.addAction(comma)

        tab = QAction("tab", self.tool_window.ui_area, checkable=True)
        tab.setChecked(self.settings.delimiter == "tab")
        tab.triggered.connect(lambda *args, delim="tab": self.settings.
                              __setattr__("delimiter", delim))
        delimiter.addAction(tab)

        space = QAction("space", self.tool_window.ui_area, checkable=True)
        space.setChecked(self.settings.delimiter == "space")
        space.triggered.connect(lambda *args, delim="space": self.settings.
                                __setattr__("delimiter", delim))
        delimiter.addAction(space)

        semicolon = QAction("semicolon",
                            self.tool_window.ui_area,
                            checkable=True)
        semicolon.setChecked(self.settings.delimiter == "semicolon")
        semicolon.triggered.connect(lambda *args, delim="semicolon": self.
                                    settings.__setattr__("delimiter", delim))
        delimiter.addAction(semicolon)

        add_header = QAction("&Include CSV header",
                             self.tool_window.ui_area,
                             checkable=True)
        add_header.setChecked(self.settings.include_header)
        add_header.triggered.connect(self.header_check)
        export.addAction(add_header)

        comma.triggered.connect(
            lambda *args, action=tab: action.setChecked(False))
        comma.triggered.connect(
            lambda *args, action=space: action.setChecked(False))
        comma.triggered.connect(
            lambda *args, action=semicolon: action.setChecked(False))

        tab.triggered.connect(
            lambda *args, action=comma: action.setChecked(False))
        tab.triggered.connect(
            lambda *args, action=space: action.setChecked(False))
        tab.triggered.connect(
            lambda *args, action=semicolon: action.setChecked(False))

        space.triggered.connect(
            lambda *args, action=comma: action.setChecked(False))
        space.triggered.connect(
            lambda *args, action=tab: action.setChecked(False))
        space.triggered.connect(
            lambda *args, action=semicolon: action.setChecked(False))

        semicolon.triggered.connect(
            lambda *args, action=comma: action.setChecked(False))
        semicolon.triggered.connect(
            lambda *args, action=tab: action.setChecked(False))
        semicolon.triggered.connect(
            lambda *args, action=space: action.setChecked(False))

        menu.setNativeMenuBar(False)
        self._menu = menu
        layout.setMenuBar(menu)
        menu.setVisible(True)

        self.tool_window.ui_area.setLayout(layout)

        self.tool_window.manage(None)

    def clear_table(self):
        are_you_sure = QMessageBox.question(
            None,
            "Clear table?",
            "Are you sure you want to clear the data table?",
        )
        if are_you_sure != QMessageBox.Yes:
            return
        self.table.setRowCount(0)

    def header_check(self, state):
        """user has [un]checked the 'include header' option on the menu"""
        if state:
            self.settings.include_header = True
        else:
            self.settings.include_header = False

    def get_csv(self):
        if self.settings.delimiter == "comma":
            delim = ","
        elif self.settings.delimiter == "space":
            delim = " "
        elif self.settings.delimiter == "tab":
            delim = "\t"
        elif self.settings.delimiter == "semicolon":
            delim = ";"

        if self.settings.include_header:
            s = delim.join(["model", "center_atom", "cone_angle"])
            s += "\n"
        else:
            s = ""

        for i in range(0, self.table.rowCount()):
            s += delim.join([
                item.data(Qt.DisplayRole)
                for item in [self.table.item(i, j) for j in range(0, 3)]
            ])
            s += "\n"

        return s

    def copy_csv(self):
        app = QApplication.instance()
        clipboard = app.clipboard()
        csv = self.get_csv()
        clipboard.setText(csv)
        self.session.logger.status("copied to clipboard")

    def save_csv(self):
        """save data on current tab to CSV file"""
        filename, _ = QFileDialog.getSaveFileName(filter="CSV Files (*.csv)")
        if filename:
            s = self.get_csv()

            with open(filename, 'w') as f:
                f.write(s.strip())

            self.session.logger.status("saved to %s" % filename)

    def del_cone(self):
        for model in self.session.models.list(type=Generic3DModel):
            if model.name.startswith("Cone angle"):
                model.delete()

    def set_ligand(self, *args):
        self.ligands = {}
        for atom in selected_atoms(self.session):
            if atom.structure not in self.ligands:
                self.ligands[atom.structure] = []
            self.ligands[atom.structure].append(atom)
        self.session.logger.status("set ligand to current selection")

    def calc_cone(self, *args):
        self.settings.cone_option = self.cone_option.currentText()
        self.settings.radii = self.radii_option.currentText()
        self.settings.display_radii = self.display_radii.checkState(
        ) == Qt.Checked
        self.settings.display_cone = self.display_cone.checkState(
        ) == Qt.Checked

        if self.cone_option.currentText() == "Tolman (Unsymmetrical)":
            method = "tolman"
        else:
            method = self.cone_option.currentText()

        radii = self.radii_option.currentText()
        return_cones = self.display_cone.checkState() == Qt.Checked
        display_radii = self.display_radii.checkState() == Qt.Checked

        # self.table.setRowCount(0)

        for center_atom in selected_atoms(self.session):
            rescol = ResidueCollection(center_atom.structure)
            at_center = rescol.find_exact(AtomSpec(center_atom.atomspec))[0]
            if center_atom.structure in self.ligands:
                comp = Component(
                    rescol.find([
                        AtomSpec(atom.atomspec)
                        for atom in self.ligands[center_atom.structure]
                    ]),
                    to_center=rescol.find_exact(AtomSpec(
                        center_atom.atomspec)),
                    key_atoms=rescol.find(BondedTo(at_center)),
                )
            else:
                comp = Component(
                    rescol.find(NotAny(at_center)),
                    to_center=rescol.find_exact(AtomSpec(
                        center_atom.atomspec)),
                    key_atoms=rescol.find(BondedTo(at_center)),
                )

            cone_angle = comp.cone_angle(
                center=rescol.find(AtomSpec(center_atom.atomspec)),
                method=method,
                radii=radii,
                return_cones=return_cones,
            )

            if return_cones:
                cone_angle, cones = cone_angle
                s = ".transparency 0.5\n"
                for cone in cones:
                    apex, base, radius = cone
                    s += ".cone   %6.3f %6.3f %6.3f   %6.3f %6.3f %6.3f   %.3f open\n" % (
                        *apex, *base, radius)

                stream = BytesIO(bytes(s, "utf-8"))
                bild_obj, status = read_bild(self.session, stream,
                                             "Cone angle %s" % center_atom)

                self.session.models.add(bild_obj, parent=center_atom.structure)

            if display_radii:
                s = ".note radii\n"
                s += ".transparency 75\n"
                color = None
                for atom in comp.atoms:
                    chix_atom = atom.chix_atom
                    if radii.lower() == "umn":
                        r = VDW_RADII[chix_atom.element.name]
                    elif radii.lower() == "bondi":
                        r = BONDI_RADII[chix_atom.element.name]

                    if color is None or chix_atom.color != color:
                        color = chix_atom.color
                        rgb = [x / 255. for x in chix_atom.color]
                        rgb.pop(-1)

                        s += ".color %f %f %f\n" % tuple(rgb)

                    s += ".sphere %f %f %f %f\n" % (*chix_atom.coord, r)

                stream = BytesIO(bytes(s, "utf-8"))
                bild_obj, status = read_bild(self.session, stream,
                                             "Cone angle radii")

                self.session.models.add(bild_obj, parent=center_atom.structure)

            row = self.table.rowCount()
            self.table.insertRow(row)

            name = QTableWidgetItem()
            name.setData(Qt.DisplayRole, center_atom.structure.name)
            self.table.setItem(row, 0, name)

            center = QTableWidgetItem()
            center.setData(Qt.DisplayRole, center_atom.atomspec)
            self.table.setItem(row, 1, center)

            ca = QTableWidgetItem()
            ca.setData(Qt.DisplayRole, "%.2f" % cone_angle)
            self.table.setItem(row, 2, ca)

            self.table.resizeColumnToContents(0)
            self.table.resizeColumnToContents(1)
            self.table.resizeColumnToContents(2)
예제 #29
0
class AaronTools_Library(ToolInstance):

    help = "https://github.com/QChASM/SEQCROW/wiki/Browse-AaronTools-Libraries-Tool"
    SESSION_ENDURING = True
    SESSION_SAVE = True

    def __init__(self, session, name):
        super().__init__(session, name)

        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)

        self.settings = _BrowseLibSettings(self.session, name)

        self.showLigKeyBool = True
        self.showSubGhostBool = True
        self.showRingWalkBool = True

        self._build_ui()

    def _build_ui(self):
        layout = QGridLayout()

        self.library_tabs = QTabWidget()

        #add a tab for ligands
        self.ligand_tab = QWidget()
        self.ligand_layout = QVBoxLayout(self.ligand_tab)
        self.lig_table = LigandTable()
        self.ligand_layout.addWidget(self.lig_table)

        showKeyAtomsCheck = QCheckBox('show key atoms')
        showKeyAtomsCheck.setToolTip(
            "ligand's coordinating atoms will be highlighted")
        showKeyAtomsCheck.toggle()
        showKeyAtomsCheck.stateChanged.connect(self.showKeyAtoms)
        self.ligand_layout.addWidget(showKeyAtomsCheck)

        self.lig_color = ColorButton('key atom color', has_alpha_channel=True)
        self.lig_color.setToolTip("highlight color for ligand's key atoms")
        self.lig_color.set_color(self.settings.key_atom_color)
        self.ligand_layout.addWidget(self.lig_color)

        openLigButton = QPushButton("open selected ligands")
        openLigButton.setToolTip(
            "ligands selected in the table will be loaded into ChimeraX")
        openLigButton.clicked.connect(self.open_ligands)
        self.ligand_layout.addWidget(openLigButton)
        self.openLigButton = openLigButton

        #add a tab for substituents
        self.substituent_tab = QWidget()
        self.substituent_layout = QVBoxLayout(self.substituent_tab)
        self.sub_table = SubstituentTable()
        self.substituent_layout.addWidget(self.sub_table)

        showGhostConnectionCheck = QCheckBox('show ghost connection')
        showGhostConnectionCheck.setToolTip(
            "ligand's coordinating atoms will be highlighted")
        showGhostConnectionCheck.toggle()
        showGhostConnectionCheck.stateChanged.connect(self.showGhostConnection)
        self.substituent_layout.addWidget(showGhostConnectionCheck)

        self.sub_color = ColorButton('ghost connection color',
                                     has_alpha_channel=True)
        self.sub_color.setToolTip("color of ghost connection")
        self.sub_color.set_color(self.settings.ghost_connection_color)
        self.substituent_layout.addWidget(self.sub_color)

        openSubButton = QPushButton("open selected substituents")
        openSubButton.setToolTip(
            "substituents selected in the table will be loaded into ChimeraX")
        openSubButton.clicked.connect(self.open_substituents)
        self.substituent_layout.addWidget(openSubButton)
        self.openSubButton = openSubButton

        #add a tab for rings
        self.ring_tab = QWidget()
        self.ring_layout = QVBoxLayout(self.ring_tab)
        self.ring_table = RingTable()
        self.ring_layout.addWidget(self.ring_table)

        showRingWalkCheck = QCheckBox('show ring walk')
        showRingWalkCheck.setToolTip(
            "arrows will show the way AaronTools traverses the ring")
        showRingWalkCheck.toggle()
        showRingWalkCheck.stateChanged.connect(self.showRingWalk)
        self.ring_layout.addWidget(showRingWalkCheck)

        self.ring_color = ColorButton('walk arrow color',
                                      has_alpha_channel=True)
        self.ring_color.setToolTip("color of walk arrows")
        self.ring_color.set_color(self.settings.ring_walk_color)
        self.ring_layout.addWidget(self.ring_color)

        openRingButton = QPushButton("open selected rings")
        openRingButton.setToolTip(
            "rings selected in the table will be loaded into ChimeraX")
        openRingButton.clicked.connect(self.open_rings)
        self.ring_layout.addWidget(openRingButton)
        self.openRingButton = openRingButton

        self.library_tabs.resize(300, 200)

        self.library_tabs.addTab(self.ligand_tab, "ligands")
        self.library_tabs.addTab(self.substituent_tab, "substituents")
        self.library_tabs.addTab(self.ring_tab, "rings")

        layout.addWidget(self.library_tabs)

        self.tool_window.ui_area.setLayout(layout)

        self.tool_window.manage(None)

    def showKeyAtoms(self, state):
        if state == QtCore.Qt.Checked:
            self.showLigKeyBool = True
        else:
            self.showLigKeyBool = False

    def open_ligands(self):
        for row in self.lig_table.table.selectionModel().selectedRows():
            if self.lig_table.table.isRowHidden(row.row()):
                continue

            lig_name = row.data()
            ligand = Component(lig_name)
            chimera_ligand = ResidueCollection(
                ligand, name=lig_name).get_chimera(self.session)

            self.session.models.add([chimera_ligand])
            apply_seqcrow_preset(chimera_ligand, fallback="Ball-Stick-Endcap")

            if self.showLigKeyBool:
                color = self.lig_color.get_color()

                color = [c / 255. for c in color]

                self.settings.key_atom_color = tuple(color)

                bild_obj = key_atom_highlight(ligand, color, self.session)

                self.session.models.add(bild_obj, parent=chimera_ligand)

    def showGhostConnection(self, state):
        if state == QtCore.Qt.Checked:
            self.showSubGhostBool = True
        else:
            self.showSubGhostBool = False

    def open_substituents(self):
        for row in self.sub_table.table.selectionModel().selectedRows():
            if self.sub_table.table.isRowHidden(row.row()):
                continue

            sub_name = row.data()
            substituent = Substituent(sub_name, name=sub_name)
            chimera_substituent = ResidueCollection(substituent).get_chimera(
                self.session)

            self.session.models.add([chimera_substituent])
            apply_seqcrow_preset(chimera_substituent,
                                 fallback="Ball-Stick-Endcap")

            if self.showSubGhostBool:
                color = self.sub_color.get_color()

                color = [c / 255. for c in color]

                self.settings.ghost_connection_color = tuple(color)

                bild_obj = ghost_connection_highlight(substituent, color,
                                                      self.session)

                self.session.models.add(bild_obj, parent=chimera_substituent)

    def showRingWalk(self, state):
        if state == QtCore.Qt.Checked:
            self.showRingWalkBool = True
        else:
            self.showRingWalkBool = False

    def open_rings(self):
        for row in self.ring_table.table.selectionModel().selectedRows():
            if self.ring_table.table.isRowHidden(row.row()):
                continue

            ring_name = row.data()
            ring = Ring(ring_name, name=ring_name)
            chimera_ring = ResidueCollection(ring.copy()).get_chimera(
                self.session)

            self.session.models.add([chimera_ring])
            apply_seqcrow_preset(chimera_ring, fallback="Ball-Stick-Endcap")

            if self.showRingWalkBool:
                color = self.ring_color.get_color()

                color = [c / 255. for c in color]

                self.ring_walk_color = tuple(color)

                bild_obj = show_walk_highlight(ring, chimera_ring, color,
                                               self.session)

                self.session.models.add(bild_obj, parent=chimera_ring)

    def display_help(self):
        """Show the help for this tool in the help viewer."""
        from chimerax.core.commands import run
        run(self.session,
            'open %s' % self.help if self.help is not None else "")
예제 #30
0
    def __init__(self, session):
        tool_name = "Help Viewer"
        ToolInstance.__init__(self, session, tool_name)
        self._pending_downloads = []
        from chimerax.ui import MainToolWindow
        self.tool_window = MainToolWindow(self)
        parent = self.tool_window.ui_area

        # UI content code
        from PyQt5.QtWidgets import QToolBar, QVBoxLayout, QAction, QLineEdit, QTabWidget, QShortcut, QStatusBar
        from PyQt5.QtGui import QIcon
        from PyQt5.QtCore import Qt
        shortcuts = (
            (Qt.CTRL + Qt.Key_0, self.page_reset_zoom),
            (Qt.CTRL + Qt.Key_T, lambda: self.create_tab(empty=True)),
            (Qt.CTRL + Qt.Key_W, self.close_current_tab),
            (Qt.CTRL + Qt.Key_Tab, lambda: self.cycle_tab(1)),
            (Qt.CTRL + Qt.SHIFT + Qt.Key_Tab, lambda: self.cycle_tab(-1)),
            (Qt.CTRL + Qt.Key_1, lambda: self.tab_n(0)),
            (Qt.CTRL + Qt.Key_2, lambda: self.tab_n(1)),
            (Qt.CTRL + Qt.Key_3, lambda: self.tab_n(2)),
            (Qt.CTRL + Qt.Key_4, lambda: self.tab_n(3)),
            (Qt.CTRL + Qt.Key_5, lambda: self.tab_n(4)),
            (Qt.CTRL + Qt.Key_6, lambda: self.tab_n(5)),
            (Qt.CTRL + Qt.Key_7, lambda: self.tab_n(6)),
            (Qt.CTRL + Qt.Key_8, lambda: self.tab_n(7)),
            (Qt.CTRL + Qt.Key_9, lambda: self.tab_n(-1)),
        )
        for shortcut, callback in shortcuts:
            sc = QShortcut(shortcut, parent)
            sc.activated.connect(callback)
        self.toolbar = tb = QToolBar()
        # tb.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 1, 0, 0)
        layout.addWidget(tb)
        parent.setLayout(layout)
        import os.path
        icon_dir = os.path.dirname(__file__)
        # attribute, text, tool tip, callback, shortcut(s), enabled
        buttons = (
            ("back", "Back", "Back to previous page", self.page_back,
             Qt.Key_Back, False),
            ("forward", "Forward", "Next page", self.page_forward,
             Qt.Key_Forward, False),
            ("reload", "Reload", "Reload page", self.page_reload,
             Qt.Key_Reload, True),
            ("new_tab", "New Tab", "New Tab",
             lambda: self.create_tab(empty=True), Qt.Key_Reload, True),
            ("zoom_in", "Zoom in", "Zoom in", self.page_zoom_in,
             [Qt.CTRL + Qt.Key_Plus, Qt.Key_ZoomIn,
              Qt.CTRL + Qt.Key_Equal], True),
            ("zoom_out", "Zoom out", "Zoom out", self.page_zoom_out,
             [Qt.CTRL + Qt.Key_Minus, Qt.Key_ZoomOut], True),
            ("home", "Home", "Home page", self.page_home, Qt.Key_HomePage,
             True),
            (None, None, None, None, None, None),
            ("search", "Search", "Search in page", self.page_search,
             Qt.Key_Search, True),
        )
        for attribute, text, tooltip, callback, shortcut, enabled in buttons:
            if attribute is None:
                tb.addSeparator()
                continue
            icon_path = os.path.join(icon_dir, "%s.svg" % attribute)
            setattr(self, attribute, QAction(QIcon(icon_path), text, tb))
            a = getattr(self, attribute)
            a.setToolTip(tooltip)
            a.triggered.connect(callback)
            if shortcut:
                if isinstance(shortcut, list):
                    a.setShortcuts(shortcut)
                else:
                    a.setShortcut(shortcut)
            a.setEnabled(enabled)
            tb.addAction(a)

        self.url = QLineEdit()
        self.url.setPlaceholderText("url")
        self.url.setClearButtonEnabled(True)
        self.url.returnPressed.connect(self.go_to)
        tb.insertWidget(self.reload, self.url)

        self.search_terms = QLineEdit()
        self.search_terms.setClearButtonEnabled(True)
        self.search_terms.setPlaceholderText("search in page")
        self.search_terms.setMaximumWidth(200)
        self.search_terms.returnPressed.connect(self.page_search)
        tb.addWidget(self.search_terms)

        self.tabs = QTabWidget(parent)
        self.tabs.setTabsClosable(True)
        self.tabs.setUsesScrollButtons(True)
        self.tabs.setTabBarAutoHide(True)
        self.tabs.setDocumentMode(False)
        self.tabs.currentChanged.connect(self.tab_changed)
        self.tabs.tabCloseRequested.connect(self.close_tab)
        layout.addWidget(self.tabs)

        self.status_bar = QStatusBar()
        layout.addWidget(self.status_bar)

        self.tool_window.manage(placement=None)

        self.profile = create_chimerax_profile(
            self.tabs,
            interceptor=self.intercept,
            download=self.download_requested)