Source code for samsifter.gui.widgets

# -*- coding: utf-8 -*-
"""
Created on Fri Dec 12 16:41:29 2014

.. moduleauthor:: Florian Aldehoff <faldehoff@student.uni-tuebingen.de>
"""

from os.path import expanduser

""" Qt4 imports """
from PyQt4.QtGui import (
    QWidget, QFileDialog, QGridLayout, QPushButton, QLineEdit, QIcon, QLabel,
    QVBoxLayout, QFormLayout, QCheckBox, QTabWidget
)
from PyQt4.QtCore import (QRect, QSize, pyqtSignal)

""" custom libraries """
from samsifter.gui.composites import (
    SliderSpinboxCombo, FileChooser, OptionSwitcher
)


[docs]class OutputWidget(QWidget): """ Representation of file output action in GUI. """ def __init__(self, parent=None): super(QWidget, self).__init__(parent) self.setGeometry(QRect(10, 1, 381, 51)) self.setObjectName("output") self.icon = QIcon.fromTheme('document-save-as') self.icon_label = QLabel() self.icon_label.setPixmap(self.icon.pixmap( self.icon.actualSize(QSize(32, 32)))) self.label = QLabel("Output") self.file_entry = QLineEdit() self.file_btn = QPushButton("Save as...") self.file_btn.pressed.connect(self.show_dialog) self.compile_box = QCheckBox("combine statistics") self.compile_box.setToolTip( "combine any temporary statistic files into one CSV" ) self.compile_box.setChecked(True) self.sam2rma_box = QCheckBox("create RMA file") self.sam2rma_box.setToolTip( "create RMA file for quick inspection in MEGAN (requires MEGAN " "5.8.3 or newer)" ) self.sam2rma_box.setChecked(False) self.sam2rma_btn = QPushButton( QIcon.fromTheme('preferences-other'), "Settings..." ) self.grid = QGridLayout(self) self.grid.addWidget(self.icon_label, 0, 0, 1, 1) self.grid.addWidget(self.label, 0, 1, 1, 1) self.grid.addWidget(self.file_entry, 0, 2, 1, 1) self.grid.addWidget(self.file_btn, 0, 3, 1, 1) self.grid.addWidget(self.sam2rma_box, 1, 1, 1, 2) self.grid.addWidget(self.sam2rma_btn, 1, 3, 1, 1) # self.grid.addWidget(self.compile_box, 2, 1, 1, 2) self.setLayout(self.grid)
[docs] def show_dialog(self): dialog = QFileDialog() dialog.setDefaultSuffix('SAM files (*.sam)') fname = dialog.getSaveFileName( self, 'Save as', expanduser("~"), "SAM (*.sam);;zipped SAM (*.sam.gz);;BAM (*.bam)" ) self.file_entry.setText(fname)
[docs] def set_filename(self, filename): """ Update filename in text box while retaining current cursor position. """ cursor = self.file_entry.cursorPosition() self.file_entry.setText(filename) self.file_entry.setCursorPosition(cursor)
[docs] def highlight(self, boolean=True): """ Indicate errors or pending actions by changing background color. """ css = "QLineEdit {background-color: #ffe08c;}" if boolean: self.file_entry.setStyleSheet(css) else: self.file_entry.setStyleSheet(None)
[docs]class InputWidget(QWidget): """ Representation of file input action in GUI. """ def __init__(self, parent=None): super(QWidget, self).__init__(parent) self.setGeometry(QRect(10, 1, 381, 51)) self.setObjectName("input") self.icon = QIcon.fromTheme('document-open') self.icon_label = QLabel() self.icon_label.setPixmap(self.icon.pixmap( self.icon.actualSize(QSize(32, 32)))) self.label = QLabel("Input") self.file_entry = QLineEdit() self.file_btn = QPushButton("Open...") self.file_btn.pressed.connect(self.show_dialog) self.grid = QGridLayout(self) self.grid.addWidget(self.icon_label, 0, 0, 1, 1) self.grid.addWidget(self.label, 0, 1, 1, 1) self.grid.addWidget(self.file_entry, 0, 2, 1, 1) self.grid.addWidget(self.file_btn, 0, 3, 1, 1) self.setLayout(self.grid)
[docs] def show_dialog(self): dialog = QFileDialog() dialog.setDefaultSuffix( 'SAM/BAM (*.sam *.SAM *.sam.gz *.SAM.GZ *.bam *.BAM)' ) fname = dialog.getOpenFileName( self, 'Open file', expanduser("~"), "SAM/BAM (*.sam *.SAM *.sam.gz *.SAM.GZ *.bam *.BAM);;" "SAM (*.sam *.SAM);;zipped SAM (*.sam.gz *.SAM.GZ);;" "BAM (*.bam *.BAM);;All files (*)" ) self.file_entry.setText(fname)
[docs] def set_filename(self, filename): """ Update filename in text box while retaining current cursor position. """ cursor = self.file_entry.cursorPosition() self.file_entry.setText(filename) self.file_entry.setCursorPosition(cursor)
[docs] def highlight(self, boolean=True): """ Indicate errors or pending actions by changing background color. """ css = "QLineEdit {background-color: #ffe08c;}" if boolean: self.file_entry.setStyleSheet(css) else: self.file_entry.setStyleSheet(None)
[docs]class FilterWidget(QWidget): """ Representation of a filter action in GUI. """ value_changed = pyqtSignal(str, name='value_changed') def __init__(self, item, parent=None): super().__init__(parent) self.item = item self.setGeometry(QRect(10, 1, 381, 51)) self.setObjectName("widget") """ Filter label and description """ title = QLabel(self.item.text()) title.setWordWrap(True) description = QLabel(self.item.get_description()) description.setWordWrap(True) # compression labels in_comp = item.get_input_compression() in_comp_str = "" if in_comp == "gzip": in_comp_str = "zipped " out_comp = item.get_output_compression() out_comp_str = "" if out_comp == "as_input": out_comp_str = in_comp_str elif out_comp == "gzip": out_comp_str = "zipped " # file format labels in_format = self.item.get_input_format() in_format_str = "" if in_format in ("SAM", "BAM"): in_format_str = in_format elif in_format == "any": in_format_str = "SAM or BAM" out_format = self.item.get_output_format() out_format_str = "" if out_format == "as_input": out_format_str = in_format_str elif out_format in ("SAM", "BAM"): out_format_str = out_format elif out_format == "any": out_format_str = "SAM or BAM" # sort order labels in_sorting = self.item.get_input_sorting() in_sorting_str = "" if in_sorting in ("queryname", "coordinate"): in_sorting_str = " (sorted by %s)" % in_sorting elif in_sorting == "unsorted": in_sorting_str = " (%s)" % in_sorting out_sorting = self.item.get_output_sorting() out_sorting_str = "" if out_sorting == "as_input": out_sorting_str = in_sorting_str elif out_sorting in ("queryname", "coordinate"): out_sorting_str = " (sorted by %s)" % out_sorting elif in_sorting == "unsorted": out_sorting_str = " (%s)" % out_sorting io_format_str = ("Input:\t %s%s%s\n" "Output:\t %s%s%s" % (in_comp_str, in_format_str, in_sorting_str, out_comp_str, out_format_str, out_sorting_str)) io_format_lbl = QLabel(io_format_str) title_layout = QVBoxLayout() # title_layout.setMargin(0) title_layout.addWidget(title) title_layout.addWidget(description) title_layout.addWidget(io_format_lbl) title_frame = QWidget(self) title_frame.setLayout(title_layout) """ Filter settings """ self.settings = QWidget(self) self.settings.setEnabled(False) self.settings_layout = QFormLayout(self.settings) self.options = QWidget(self) self.options.setEnabled(False) self.options_layout = QFormLayout(self.options) self.toolbox = QTabWidget(self) self.toolbox.setEnabled(False) self.toolbox.addTab(self.settings, "Required") self.toolbox.addTab(self.options, "Optional") self.parameters = [] for param in self.item.get_parameters(): self.add_parameter(param) icon = QIcon.fromTheme('view-filter') icon_label = QLabel() icon_label.setPixmap(icon.pixmap(icon.actualSize(QSize(32, 32)))) """ Put it all together """ layout = QVBoxLayout(self) layout.setMargin(0) layout.addWidget(title_frame) layout.addWidget(self.toolbox) self.setLayout(layout) """ event handlers """
[docs] def on_value_change(self, value): self.value_changed.emit("value in editor changed to %s" % value)
""" Getters & Setters """
[docs] def set_name(self, name): self.name = name
[docs] def add_parameter(self, parameter): # import here to avoid circular imports! from samsifter.models.parameter import (FilterParameter, FilterThreshold, FilterSwitch, FilterFilepath) self.parameters.append(parameter) if isinstance(parameter, FilterThreshold): widget = SliderSpinboxCombo(self, parameter.get_minimum(), parameter.get_maximum(), parameter.get_default(), parameter.get_precision()) widget.set_value(parameter.get_value()) widget.setToolTip(parameter.get_description()) widget.spinner.valueChanged.connect(parameter.set_value) widget.spinner.valueChanged.connect(self.on_value_change) elif isinstance(parameter, FilterSwitch): widget = OptionSwitcher(self, parameter.get_options()) widget.set_current_index(parameter.get_value()) widget.setToolTip(parameter.get_description()) widget.group.buttonClicked[int].connect(parameter.set_value) widget.group.buttonClicked[int].connect(self.on_value_change) elif isinstance(parameter, FilterFilepath): widget = FileChooser(self) widget.set_filename(parameter.get_value()) widget.setToolTip(parameter.get_description()) # ensure immediate update for revalidation widget.lineedit.textChanged.connect(widget.set_filename) widget.lineedit.textChanged.connect(parameter.set_value) widget.lineedit.textChanged.connect(self.on_value_change) elif isinstance(parameter, FilterParameter): widget = QCheckBox(self) widget.setChecked(parameter.get_value()) widget.setToolTip(parameter.get_description()) widget.toggled.connect(parameter.set_value) widget.toggled.connect(self.on_value_change) if parameter.is_required(): self.settings.setEnabled(True) self.toolbox.setEnabled(True) self.settings_layout.addRow(parameter.get_form_text(), widget) else: self.options.setEnabled(True) self.toolbox.setEnabled(True) self.options_layout.addRow(parameter.get_form_text(), widget) self.update()