예제 #1
0
    def _create_group_widget(self, group):
        group_widget = QtGui.QGroupBox()
        last_row = self._grid_layout.rowCount()
        self._grid_layout.addWidget(group_widget, last_row, 0, 1, 2)
        lay1 = QtGui.QVBoxLayout()
        lay1.setContentsMargins(0, 0, 0, 0)
        lay2 = QtGui.QHBoxLayout()
        lay1.addLayout(lay2)
        lay2.setContentsMargins(10, 0, 0, 0)
        lay2.addWidget(QtGui.QLabel('<html><em>%s</em></html>' % group))
        lay2.addStretch(1)
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_down")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        group_widget.fold_button = QtGui.QPushButton(icon, '')
        group_widget.fold_button.setFixedSize(30, 20)
        lay2.addWidget(group_widget.fold_button)
        widget = QtGui.QWidget()
        group_widget.setLayout(lay1)
        lay1.addWidget(widget)
        group_widget.hideable_widget = widget
        layout = QtGui.QGridLayout()
        widget.setLayout(layout)
        layout.setAlignment(QtCore.Qt.AlignTop)
        layout.setSpacing(3)
        layout.setContentsMargins(5, 5, 5, 5)
        group_widget.setAlignment(QtCore.Qt.AlignLeft)

        visible_groups = getattr(self.controller, 'visible_groups', set())
        if group in visible_groups:
            show = True
        else:
            show = False
        group_widget.hideable_widget.setVisible(show)

        if not show:
            icon = QtGui.QIcon()
            icon.addPixmap(
                QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_right")),
                QtGui.QIcon.Normal, QtGui.QIcon.Off)
            group_widget.fold_button.setIcon(icon)

        #group_widget.fold_button.clicked.connect(SomaPartial(
        #self._toggle_group_visibility, group))
        # FIXME: if we use this, self gets deleted somewhere. This is not
        # normal.
        group_widget.fold_button.clicked.connect(
            partial(self.__class__._toggle_group_visibility, weak_proxy(self),
                    group))

        return group_widget
예제 #2
0
def inlineGUI(self, values, pview, parent, externalRunButton=False):
    from soma.qt_gui.qt_backend import QtGui
    from brainvisa.processing.qtgui import neuroProcessesGUI
    vb = QtGui.QWidget()
    lay = QtGui.QVBoxLayout(vb)
    lay.addWidget(
        neuroProcessesGUI.ProcessView.defaultInlineGUI(pview, vb,
                                                       externalRunButton,
                                                       None))
    lay.addWidget(
        QtGui.QLabel(
            _t_('The SPM paths have not been setup in the configuration.\nCurrently, processes using SPM might not work,\nand the SPM database (normalization templates...) cannot be used.\nThis process can try to detect it and set it in the configuration.\nYou should re-open any process depending on SPM afterwards.'
                ), vb))
    return vb
예제 #3
0
 def _completion_progress_changed(self, obj, name, old, new):
     completion_engine = getattr(self.attributed_process,
                                 'completion_engine', None)
     if completion_engine is not None:
         if not hasattr(self, 'progressdialog'):
             self.progressdialog = QtGui.QWidget()
             self.layout().insertWidget(1, self.progressdialog)
             layout = QtGui.QHBoxLayout()
             self.progressdialog.setLayout(layout)
             layout.addWidget(QtGui.QLabel('Completion progress:'))
             self.progressbar = QtGui.QProgressBar()
             layout.addWidget(self.progressbar)
             self.progressbar.setRange(0, 100)
         value = int(round(100 * completion_engine.completion_progress
                     / completion_engine.completion_progress_total))
         self.progressbar.setValue(value)
         if value != 100:
             self.progressdialog.show()
             QtGui.qApp.processEvents()
         else:
             self.progressdialog.hide()
예제 #4
0
    def create_widget(parent, control_name, control_value, trait,
                      label_class=None):
        """ Method to create the dict widget.

        Parameters
        ----------
        parent: QWidget (mandatory)
            the parent widget
        control_name: str (mandatory)
            the name of the control we want to create
        control_value: dict of items (mandatory)
            the default control value
        trait: Tait (mandatory)
            the trait associated to the control
        label_class: Qt widget class (optional, default: None)
            the label widget will be an instance of this class. Its constructor
            will be called using 2 arguments: the label string and the parent
            widget.

        Returns
        -------
        out: 2-uplet
            a two element tuple of the form (control widget: ,
            associated labels: (a label QLabel, the tools QWidget))
        """
        # Get the inner trait: expect only one inner trait
        # note: trait.inner_traits might be a method (ListInt) or a tuple
        # (List), whereas trait.handler.inner_trait is always a method
        if len(trait.handler.inner_traits()) != 2:
            raise Exception(
                "Expect two inner traits in Dict control. Trait '{0}' "
                "inner traits are '{1}'.".format(
                    control_name, trait.inner_traits))
        inner_trait = trait.handler.inner_traits()[1]

        # Create the dict widget: a frame
        frame = QtGui.QFrame(parent=parent)
        frame.setFrameShape(QtGui.QFrame.StyledPanel)

        # Create tools to interact with the dict widget: expand or collapse -
        # add a dict item - remove a dict item
        tool_widget = QtGui.QWidget(parent)
        layout = QtGui.QHBoxLayout()
        layout.addStretch(1)
        tool_widget.setLayout(layout)
        # Create the tool buttons
        resize_button = QtGui.QToolButton()
        add_button = QtGui.QToolButton()
        layout.addWidget(resize_button)
        layout.addWidget(add_button)
        # Set the tool icons
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/add")),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        add_button.setIcon(icon)
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_down")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        resize_button.setIcon(icon)
        resize_button.setFixedSize(30, 22)
        add_button.setFixedSize(30, 22)

        # Create a new controller that contains length 'control_value' inner
        # trait elements
        controller = DictController()
        for name, inner_control_values in six.iteritems(control_value):
            controller.add_trait(str(name), inner_trait)
            setattr(controller, str(name), inner_control_values)

        # Create the associated controller widget
        controller_widget = ControllerWidget(controller, parent=frame,
                                             live=True, editable_labels=True)

        # Store some parameters in the dict widget
        frame.inner_trait = inner_trait
        frame.trait = trait
        frame.controller = controller
        frame.controller_widget = controller_widget
        frame.connected = False

        # Add the dict controller widget to the dict widget
        frame.setLayout(controller_widget.layout())

        # Set some callback on the dict control tools
        # Resize callback
        resize_hook = partial(
            DictControlWidget.expand_or_collapse, weak_proxy(frame),
            weak_proxy(resize_button))
        resize_button.clicked.connect(resize_hook)
        # Add dict item callback
        add_hook = partial(
            DictControlWidget.add_dict_item, parent, control_name, frame)
        add_button.clicked.connect(add_hook)

        # Create the label associated with the dict widget
        control_label = trait.label
        if control_label is None:
            control_label = control_name
        if label_class is None:
            label_class = QtGui.QLabel
        if control_label is not None:
            label = label_class(control_label, parent)
        else:
            label = None

        controller_widget.main_controller_def = (DictControlWidget, parent,
                                                 control_name, frame)
        return (frame, (label, tool_widget))
예제 #5
0
    def create_widget(parent,
                      control_name,
                      control_value,
                      trait,
                      label_class=None):
        """ Method to create the file widget.

        Parameters
        ----------
        parent: QWidget (mandatory)
            the parent widget
        control_name: str (mandatory)
            the name of the control we want to create
        control_value: str (mandatory)
            the default control value
        trait: Tait (mandatory)
            the trait associated to the control
        label_class: Qt widget class (optional, default: None)
            the label widget will be an instance of this class. Its constructor
            will be called using 2 arguments: the label string and the parent
            widget.

        Returns
        -------
        out: 2-uplet
            a two element tuple of the form (control widget: QWidget with two
            elements, a QLineEdit in the 'path' parameter and a browse button
            in the 'browse' parameter, associated label: QLabel)
        """
        # Create the widget that will be used to select a file
        widget = QtGui.QWidget(parent)
        layout = QtGui.QHBoxLayout()
        layout.setSpacing(0)
        layout.setSizeConstraint(QtGui.QLayout.SetMinimumSize)
        layout.setContentsMargins(0, 0, 0, 0)
        widget.setLayout(layout)
        # Create a widget to print the file path
        path = TimeredQLineEdit(widget)
        layout.addWidget(path)
        widget.path = path
        # Create a browse button
        button = QtGui.QPushButton("...", widget)
        button.setObjectName('file_button')
        button.setStyleSheet('QPushButton#file_button '
                             '{padding: 2px 10px 2px 10px; margin: 0px;}')
        layout.addWidget(button)
        widget.browse = button

        # Add a widget parameter to tell us if the widget is already connected
        widget.connected = False

        # Add a parameter to tell us if the widget is optional
        widget.optional = trait.optional
        widget.output = trait.output

        # Set a callback on the browse button
        control_class = parent.get_control_class(trait)
        browse_hook = partial(control_class.onBrowseClicked,
                              weak_proxy(widget))
        widget.browse.clicked.connect(browse_hook)

        # Create the label associated with the string widget
        control_label = trait.label
        if control_label is None:
            control_label = control_name
        if label_class is None:
            label_class = QtGui.QLabel
        if control_label is not None:
            label = label_class(control_label, parent)
        else:
            label = None

        return (widget, label)
예제 #6
0
    def create_widget(parent,
                      control_name,
                      control_value,
                      trait,
                      label_class=None,
                      user_data=None):
        """ Method to create the list widget.

        Parameters
        ----------
        parent: QWidget (mandatory)
            the parent widget
        control_name: str (mandatory)
            the name of the control we want to create
        control_value: list of items (mandatory)
            the default control value
        trait: Tait (mandatory)
            the trait associated to the control
        label_class: Qt widget class (optional, default: None)
            the label widget will be an instance of this class. Its constructor
            will be called using 2 arguments: the label string and the parent
            widget.

        Returns
        -------
        out: 2-uplet
            a two element tuple of the form (control widget: ,
            associated labels: (a label QLabel, the tools QWidget))
        """
        # Get the inner trait: expect only one inner trait
        # note: trait.inner_traits might be a method (ListInt) or a tuple
        # (List), whereas trait.handler.inner_trait is always a method
        if len(trait.handler.inner_traits()) != 1:
            raise Exception(
                "Expect only one inner trait in List control. Trait '{0}' "
                "inner trait is '{1}'.".format(control_name,
                                               trait.handler.inner_traits()))
        inner_trait = trait.handler.inner_traits()[0]

        # Create the widget
        frame = QtGui.QFrame()
        frame.setFrameShape(QtGui.QFrame.StyledPanel)
        frame.user_data = user_data
        layout = QtGui.QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        frame.setLayout(layout)
        #item = QtGui.QLabel('&lt;list of %s&gt;'
        #% str(inner_trait.trait_type.__class__.__name__))
        #item.setTextInteractionFlags(QtCore.Qt.TextSelectableByKeyboard |
        #QtCore.Qt.TextSelectableByMouse)
        #item.setFrameStyle(QtGui.QFrame.StyledPanel | QtGui.QFrame.Sunken)
        #layout.addWidget(item)

        # Create tools to interact with the list widget: expand or collapse -
        # add a list item - remove a list item
        tool_widget = QtGui.QWidget(parent)
        layout.addWidget(tool_widget)

        layout = QtGui.QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(2)
        tool_widget.setLayout(layout)
        # Store some parameters in the list widget
        frame.inner_trait = inner_trait
        frame.trait = trait
        frame.connected = False
        if control_value is traits.Undefined:
            control_value = []
        elif not isinstance(control_value, (list, tuple)):
            # in nipype MultiPath, single values are not in a list
            control_value = [control_value]
        frame.trait_name = control_name

        # Create the label associated with the list widget
        control_label = trait.label
        if control_label is None:
            control_label = control_name
        if label_class is None:
            label_class = QtGui.QLabel
        if control_label is not None:
            label = label_class(control_label, parent)
        else:
            label = None
        frame.label_class = label_class

        # view the model
        items = OffscreenListControlWidget.partial_view_widget(
            weak_proxy(parent), weak_proxy(frame), control_value)
        layout.addWidget(items)
        #layout.addWidget(QtGui.QLabel('...'))
        frame.control_widget = items
        frame.controller = items.control_widget.controller
        frame.controller_widget = items.control_widget.controller_widget

        # Create the tool buttons
        edit_button = QtGui.QToolButton()
        layout.addWidget(edit_button)
        # Set the tool icons
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/add")),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        edit_button.setIcon(icon)
        edit_button.setFixedSize(30, 22)

        #layout.addStretch(1)

        # Set some callback on the list control tools
        # Resize callback
        edit_hook = partial(OffscreenListControlWidget.edit_elements,
                            weak_proxy(parent), weak_proxy(frame),
                            weak_proxy(edit_button))
        edit_button.clicked.connect(edit_hook)

        return (frame, label)
    def __init__(self, missing_inputs, overwritten_outputs, parent=None):
        super(PipelineFileWarningWidget, self).__init__(
            QtCore.Qt.Vertical, parent)
        """
        Builds the check widget.

        Parameters
        ----------
        missing_inputs: mapping iterable (mandatory)
            a dict node: (list of pairs (param_name, file_name))
            as output of
            :py:func:`capsul.pipeline_tools.nodes_with_missing_inputs`
        overwritten_outputs: mapping iterable (mandatory)
            a dict node: (list of pairs (param_name, file_name))
            as output of
            :py:func:`capsul.pipeline_tools.nodes_with_existing_outputs`
        parent: QWidget (optional)
            parent widget
        """
        splitter = self
        widget1 = QtGui.QWidget(splitter)
        layout1 = QtGui.QVBoxLayout(widget1)
        widget2 = QtGui.QWidget(splitter)
        layout2 = QtGui.QVBoxLayout(widget2)
        label = QtGui.QLabel()
        layout1.addWidget(label)

        text = '<h1>Pipeline file parameters problems</h1>\n'

        if len(missing_inputs) == 0:
            text += '<h2>Inputs: OK</h2>\n' \
                '<p>All input file are present.</p>\n'
            label.setText(text)
        else:
            text += '<h2>Inputs: missing files</h2>\n'
            label.setText(text)

            table = QtGui.QTableWidget()
            layout1.addWidget(table)
            table.setColumnCount(3)
            sizes = [len(l) for node, l in six.iteritems(missing_inputs)]
            table.setRowCount(sum(sizes))
            table.setHorizontalHeaderLabels(
                ['node', 'parameter', 'filename'])
            row = 0
            for node_name, items in six.iteritems(missing_inputs):
                for param_name, file_name in items:
                    if not file_name or file_name is traits.Undefined:
                        file_name = '<temp. file>'
                    table.setItem(row, 0, QtGui.QTableWidgetItem(node_name))
                    table.setItem(row, 1,
                                  QtGui.QTableWidgetItem(param_name))
                    table.setItem(row, 2, QtGui.QTableWidgetItem(file_name))
                    row += 1
            table.setSortingEnabled(True)
            table.resizeColumnsToContents()

        label_out = QtGui.QLabel()
        layout2.addWidget(label_out)
        if len(overwritten_outputs) == 0:
            text = '<h2>Outputs: OK</h2>\n' \
                '<p>No output file will be overwritten.</p>\n'
            label_out.setText(text)
        else:
            text = '<h2>Outputs: overwritten files</h2>\n'
            label_out.setText(text)

            table = QtGui.QTableWidget()
            layout2.addWidget(table)
            table.setColumnCount(3)
            sizes = [len(l) for node, l in six.iteritems(overwritten_outputs)]
            table.setRowCount(sum(sizes))
            table.setHorizontalHeaderLabels(
                ['node', 'parameter', 'filename'])
            row = 0
            for node_name, items in six.iteritems(overwritten_outputs):
                for param_name, file_name in items:
                    if not file_name or file_name is traits.Undefined:
                        file_name = '<temp. file>'
                    table.setItem(row, 0, QtGui.QTableWidgetItem(node_name))
                    table.setItem(row, 1,
                                  QtGui.QTableWidgetItem(param_name))
                    table.setItem(row, 2, QtGui.QTableWidgetItem(file_name))
                    row += 1
            table.setSortingEnabled(True)
            table.resizeColumnsToContents()
예제 #8
0
    def _fill_trees(self):
        """ Method to insert processing parameters in the class trees.
        """
        # Generate structures that contain all viewers and all processings
        # status - metainforamtion
        viewers_struct = {}
        processings_struct = []
    
        # Go through all the controller (pipeline) nodes.
        for node_name, node in six.iteritems(self.controller.nodes):

            # If the current node is a processing node
            if node_name != "" and node.node_type != "view_node":

                # First browse the current node to get processings and viewers
                process_nodes = []
                view_nodes = []
                self.browse_node(
                    node, process_nodes, view_nodes, self.controller)

                # Set process logs
                #for process_node in process_nodes:
                #    widget = LogWidget(process_node)
                #    widget.setParent(root.treeWidget())
                #    child.treeWidget().setItemWidget(child, 3, widget)

                # Fill the processing structure
                for processing_node in process_nodes:
                    processings_struct.append({
                        "name": processing_node.name,
                        "log": processing_node.process.log_file or "No log"})

                # Fill the viewer structure
                for viewer_node, pipeline in view_nodes:

                    # Create a viewer widget (a simple press button)
                    widget = ViewerWidget(viewer_node.name, pipeline, None)
                                          #self._study_config)

                    # Store the widget in the corresponding structure
                    title = self._title_for(pipeline.name)
                    if title not in viewers_struct:
                        viewers_struct[title] = []
                    viewers_struct[title].append(widget)


            # If the current node is a viewer node
            elif node.node_type == "view_node":

                # Create a viewer widget (a simple press button)
                widget = ViewerWidget(node_name, self.controller, None)
                                      #self._study_config)

                # Store the widget in the corresponding structure
                title = self._title_for(self.controller.name)
                if title not in viewers_struct:
                    viewers_struct[title] = []
                viewers_struct[title].append(widget)


        # Fill the viewer tree widget
        viewer_parent = self.viewer_tree.invisibleRootItem()
        for pipeline_title, viewer_widgets in six.iteritems(viewers_struct):

            # Create a new tree item
            viewer_child = QtGui.QTreeWidgetItem(viewer_parent)
            viewer_child.setText(0, pipeline_title)

            # Set the viewer widgets in a layout
            widget_layout = QtGui.QHBoxLayout()
            widget_layout.setSpacing(0)
            widget_layout.setSizeConstraint(QtGui.QLayout.SetMinimumSize)
            widget_layout.setContentsMargins(0, 0, 0, 0)
            widget_layout.addStretch(1)
            for widget in viewer_widgets:
                widget = QtGui.QToolButton()
                widget_layout.addWidget(widget)

            # Set the final widget tree item
            widget = QtGui.QWidget(viewer_child.treeWidget())
            widget.setLayout(widget_layout)
            viewer_child.treeWidget().setItemWidget(viewer_child, 1, widget)

        # Fill the pboard tree widget
        board_parent = self.board_tree.invisibleRootItem()
        for process_info in processings_struct:

            # Create a new tree item
            board_child = QtGui.QTreeWidgetItem(board_parent)
            board_child.setText(0, process_info["name"])
            board_child.setText(4, process_info["log"])
예제 #9
0
    def __init__(self, attributed_process, enable_attr_from_filename=False,
                 enable_load_buttons=False, override_control_types=None,
                 separate_outputs=True, user_data=None, userlevel=0,
                 scroll=True):
        """
        Parameters
        ----------
        attributed_process: Process instance
            process with attributes to be displayed
        enable_attr_from_filename: bool (optional)
            if enabled, it will be possible to specify an input filename to
            build attributes from
        override_control_types: dict (optional)
            if given, this is a "factory" dict assigning new controller editor
            types to some traits types in the parameters controller.
        separate_outputs: bool
            if True, inputs and outputs (traits with output=True set) will
            be separated into two boxes.
        user_data: any type (optional)
            optional user data that can be accessed by individual control
            editors
        userlevel: int
            the current user level: some traits may be marked with a non-zero userlevel, and will only be visible if the ControllerWidget userlevel is more than (or equal) the trait level.
        scroll: bool
            if True, the widget includes scrollbars in the parameters and
            attributes sections when needed, otherwise it will be a fixed size
            widget.
        """
        super(AttributedProcessWidget, self).__init__()
        self.setLayout(QtGui.QVBoxLayout())
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.attributed_process = attributed_process
        self._show_completion = False
        self.user_data = user_data
        self.separate_outputs = separate_outputs
        self._userlevel = userlevel

        process = attributed_process
        completion_engine = getattr(process, 'completion_engine', None)

        if completion_engine is not None:
            splitter = QtGui.QSplitter(QtCore.Qt.Vertical)
            self.layout().addWidget(splitter)
            spl_up = QtGui.QWidget()
            spl_up.setLayout(QtGui.QVBoxLayout())
            splitter.addWidget(spl_up)
            spl_down = QtGui.QWidget()
            spl_down.setLayout(QtGui.QVBoxLayout())
            splitter.addWidget(spl_down)
        else:
            spl_up = self
            spl_down = self

        filename_widget = None
        if enable_attr_from_filename and completion_engine is not None:
            c = Controller()
            c.add_trait('attributes_from_input_filename', File(optional=True))
            filename_widget = ControllerWidget(c, live=True,
                                               user_data=user_data)
            spl_up.layout().addWidget(filename_widget)
            self.input_filename_controller = c
            c.on_trait_change(self.on_input_filename_changed,
                              'attributes_from_input_filename', dispatch='ui')
            filename_widget.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                          QtGui.QSizePolicy.Fixed)

        # groupbox area to show attributes
        attrib_widget = QtGui.QGroupBox('Attributes:')
        attrib_widget.setFlat(True)
        attrib_widget.setAlignment(QtCore.Qt.AlignLeft)
        attrib_widget.setLayout(QtGui.QVBoxLayout())
        self.attrib_widget = attrib_widget
        spl_up.layout().addWidget(attrib_widget)
        attrib_widget.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                    QtGui.QSizePolicy.Preferred)

        hlay = QtGui.QHBoxLayout()
        spl_up.layout().addLayout(hlay)
        # CheckBox to completion rules or not
        self.checkbox_fom = QtGui.QCheckBox('Follow completion rules')
        self.checkbox_fom.setChecked(True)
        self.checkbox_fom.stateChanged.connect(self.on_use_fom_change)
        hlay.addWidget(self.checkbox_fom)

        # Button Show/Hide completion
        self.btn_show_completion = QtGui.QCheckBox('Show completion')
        self.btn_show_completion.setSizePolicy(QtGui.QSizePolicy.Fixed,
                                               QtGui.QSizePolicy.Fixed)
        hlay.addWidget(self.btn_show_completion)
        self.btn_show_completion.stateChanged.connect(self.on_show_completion)

        params = QtGui.QWidget()
        playout = QtGui.QVBoxLayout()
        params.setLayout(playout)
        if scroll:
            scroll_a = QtGui.QScrollArea()
            scroll_a.setWidgetResizable(True)
            scroll_a.setWidget(params)
            spl_up.layout().addWidget(scroll_a)
            scroll_a.setSizePolicy(QtGui.QSizePolicy.Preferred,
                                   QtGui.QSizePolicy.Preferred)
            params.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                 QtGui.QSizePolicy.Preferred)
            CWidgetClass = ScrollControllerWidget
        else:
            spl_up.layout().addWidget(params)
            CWidgetClass = ControllerWidget

        # groupbox area to show completion
        if separate_outputs:
            param_widget = QtGui.QGroupBox('Inputs:')
        else:
            param_widget = QtGui.QGroupBox('Parameters:')
        param_widget.setFlat(True)
        param_widget.setAlignment(QtCore.Qt.AlignLeft)
        playout.addWidget(param_widget)
        param_widget.setLayout(QtGui.QVBoxLayout())
        param_widget.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)
        if separate_outputs:
            out_widget = QtGui.QGroupBox('Outputs:')
            out_widget.setFlat(True)
            out_widget.setAlignment(QtCore.Qt.AlignLeft)
            playout.addWidget(out_widget)
            out_widget.setLayout(QtGui.QVBoxLayout())
            out_widget.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                     QtGui.QSizePolicy.Expanding)

        # use concise shape for lists GUI
        from  soma.qt_gui.controls import OffscreenListControlWidget
        control_types_a = {'List': OffscreenListControlWidget}
        control_types_p = {'List': OffscreenListControlWidget}
        if override_control_types:
            control_types_p.update(override_control_types)
        #ControllerWidget._defined_controls['List'] = OffscreenListControlWidget

        # Create controller widget for process and object_attribute
        sel = None
        if separate_outputs:
            sel = 'inputs'
        self.controller_widget = ControllerWidget(process, live=True,
            parent=param_widget, override_control_types=control_types_p,
            user_data=user_data, userlevel=userlevel, select_controls=sel)
        if separate_outputs:
            self.outputs_cwidget = ControllerWidget(process, live=True,
            parent=out_widget, override_control_types=control_types_p,
            user_data=user_data, userlevel=userlevel,
            select_controls='outputs')

        show_ce = (completion_engine is not None
                   and len(
                      completion_engine.get_attribute_values().user_traits())
                          != 0)

        if completion_engine is not None:
            self.controller_widget2 = CWidgetClass(
                completion_engine.get_attribute_values(),
                live=True, parent=attrib_widget,
                override_control_types=control_types_a, user_data=user_data,
                userlevel=userlevel)
            completion_engine.get_attribute_values().on_trait_change(
                completion_engine.attributes_changed, 'anytrait')
        else:
            self.controller_widget2 = CWidgetClass(
                Controller(), override_control_types=control_types_a,
                user_data=user_data, userlevel=userlevel)

        # Set controller of attributes and controller of process for each
        # corresponding area
        param_widget.layout().addWidget(self.controller_widget)
        if separate_outputs:
            out_widget.layout().addWidget(self.outputs_cwidget)
        attrib_widget.layout().addWidget(self.controller_widget2)

        if enable_load_buttons and completion_engine is not None:
            io_lay = QtGui.QHBoxLayout()
            self.layout().addLayout(io_lay)
            self.btn_load_json = QtGui.QPushButton('Load attributes')
            io_lay.addWidget(self.btn_load_json)
            self.btn_load_json.clicked.connect(self.on_btn_load_json)
            self.btn_save_json = QtGui.QPushButton('Save attributes')
            io_lay.addWidget(self.btn_save_json)
            self.btn_save_json.clicked.connect(self.on_btn_save_json)

        if not show_ce:
            if filename_widget:
                filename_widget.hide()
            attrib_widget.hide()
            self.checkbox_fom.hide()
            self.btn_show_completion.hide()
            if hasattr(self, 'btn_load_json'):
                self.btn_load_json.hide()
                self.btn_save_json.hide()
            self.show_completion(True) # hide file parts
        else:
            self.show_completion(False) # hide file parts

        if completion_engine is not None:
            completion_engine.on_trait_change(
                self._completion_progress_changed, 'completion_progress',
                dispatch='ui')
예제 #10
0
    def create_widget(parent,
                      control_name,
                      control_value,
                      trait,
                      label_class=None,
                      max_items=0):
        """ Method to create the list widget.

        Parameters
        ----------
        parent: QWidget (mandatory)
            the parent widget
        control_name: str (mandatory)
            the name of the control we want to create
        control_value: list of items (mandatory)
            the default control value
        trait: Tait (mandatory)
            the trait associated to the control
        label_class: Qt widget class (optional, default: None)
            the label widget will be an instance of this class. Its constructor
            will be called using 2 arguments: the label string and the parent
            widget.
        max_items: int (optional)
            display at most this number of items. Defaults to 0: no limit.

        Returns
        -------
        out: 2-uplet
            a two element tuple of the form (control widget: ,
            associated labels: (a label QLabel, the tools QWidget))
        """
        # Get the inner trait: expect only one inner trait
        # note: trait.inner_traits might be a method (ListInt) or a tuple
        # (List), whereas trait.handler.inner_trait is always a method
        if len(trait.handler.inner_traits()) == 1:
            inner_trait = trait.handler.inner_traits()[0]
        elif len(trait.handler.inner_traits()) == 0:
            # maybe a generic list, or a compount trait
            if hasattr(trait.handler, 'handlers') \
                    and len(trait.handler.handlers) > 0 \
                    and hasattr(trait.handler.handlers[0], 'inner_traits') \
                    and len(trait.handler.handlers[0].inner_traits()) > 0:
                inner_trait = trait.handler.handlers[0].inner_traits()[0]
            else:
                # can't determine type, fallback to string
                inner_trait = traits.Str()
        else:
            raise Exception(
                "Expect only one inner trait in List control. Trait '{0}' "
                "inner trait is '{1}'.".format(control_name,
                                               trait.handler.inner_traits()))

        if control_value is traits.Undefined:
            control_value = []

        # Create the list widget: a frame
        parent = get_ref(parent)
        frame = QtGui.QFrame(parent=parent)
        #frame.setFrameShape(QtGui.QFrame.StyledPanel)
        frame.setFrameShape(QtGui.QFrame.NoFrame)

        # Create tools to interact with the list widget: expand or collapse -
        # add a list item - remove a list item
        tool_widget = QtGui.QWidget(parent)
        layout = QtGui.QHBoxLayout()
        layout.addStretch(1)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(2)
        tool_widget.setLayout(layout)
        # Create the tool buttons
        resize_button = QtGui.QToolButton()
        add_button = QtGui.QToolButton()
        delete_button = QtGui.QToolButton()
        layout.addWidget(resize_button)
        layout.addWidget(add_button)
        layout.addWidget(delete_button)
        # Set the tool icons
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/add")),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        add_button.setIcon(icon)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/delete")),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        delete_button.setIcon(icon)
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_down")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        resize_button.setIcon(icon)
        resize_button.setFixedSize(30, 22)
        add_button.setFixedSize(40, 22)
        delete_button.setFixedSize(40, 22)

        menu = QtGui.QMenu()
        menu.addAction(
            'Enter list',
            partial(ListControlWidget.enter_list, weak_proxy(parent),
                    control_name, weak_proxy(frame)))
        menu.addAction(
            'Load list',
            partial(ListControlWidget.load_list, weak_proxy(parent),
                    control_name, weak_proxy(frame)))
        if isinstance(inner_trait.trait_type, traits.File) \
                or isinstance(inner_trait.trait_type, traits.Directory):
            menu.addAction(
                'Select files',
                partial(ListControlWidget.select_files, weak_proxy(parent),
                        control_name, weak_proxy(frame)))
        add_button.setMenu(menu)

        menu = QtGui.QMenu()
        menu.addAction(
            'Clear all',
            partial(ListControlWidget.clear_all, weak_proxy(parent),
                    control_name, weak_proxy(frame), trait.trait_type.minlen))
        delete_button.setMenu(menu)

        # Create a new controller that contains length 'control_value' inner
        # trait elements
        controller = ListController()

        if inner_trait.groups:
            del inner_trait.groups

        n = max_items
        if n == 0:
            n = len(control_value)

        for cnt, inner_control_values in enumerate(control_value[:n]):
            controller.add_trait(str(cnt), inner_trait)
            #if inner_trait.groups:
            #del trait(str(cnt)).groups
            setattr(controller, str(cnt), inner_control_values)

        # Create the associated controller widget
        controller_widget = ControllerWidget(controller,
                                             parent=frame,
                                             live=True)
        controller_widget.setObjectName('inner_controller')
        controller_widget.setStyleSheet(
            'ControllerWidget#inner_controller { padding: 0px; }')

        # Store some parameters in the list widget
        frame.inner_trait = inner_trait
        frame.trait = trait
        frame.controller = controller
        frame.controller_widget = controller_widget
        frame.connected = False
        frame.max_items = max_items

        # Add the list controller widget to the list widget
        frame.setLayout(controller_widget.layout())
        frame.layout().setContentsMargins(0, 0, 0, 0)
        frame.setObjectName('inner_frame')
        frame.setStyleSheet('QFrame#inner_frame { padding: 0px; }')

        # Set some callback on the list control tools
        # Resize callback
        resize_hook = partial(ListControlWidget.expand_or_collapse,
                              weak_proxy(frame), weak_proxy(resize_button))
        resize_button.clicked.connect(resize_hook)
        # Add list item callback
        add_hook = partial(ListControlWidget.add_list_item, weak_proxy(parent),
                           control_name, weak_proxy(frame))
        add_button.clicked.connect(add_hook)
        # Delete list item callback
        delete_hook = partial(ListControlWidget.delete_list_item,
                              weak_proxy(parent), control_name,
                              weak_proxy(frame))
        delete_button.clicked.connect(delete_hook)

        # Create the label associated with the list widget
        control_label = trait.label
        if control_label is None:
            control_label = control_name
        if label_class is None:
            label_class = QtGui.QLabel
        if control_label is not None:
            label = label_class(control_label, parent)
        else:
            label = None

        return (frame, (label, tool_widget))
예제 #11
0
    def create_widget(parent,
                      control_name,
                      control_value,
                      trait,
                      label_class=None):
        """ Method to create the controller widget.

        Parameters
        ----------
        parent: QWidget (mandatory)
            the parent widget
        control_name: str (mandatory)
            the name of the control we want to create
        control_value: instance of Controller (mandatory)
            the default control value
        trait: Tait (mandatory)
            the trait associated to the control
        label_class: Qt widget class (optional, default: None)
            the label widget will be an instance of this class. Its constructor
            will be called using 2 arguments: the label string and the parent
            widget.

        Returns
        -------
        out: 2-uplet
            a two element tuple of the form (control widget: ,
            associated labels: (a label QLabel, the tools QWidget))
        """
        # Create the list widget: a frame
        frame = QtGui.QFrame(parent=parent)
        frame.setFrameShape(QtGui.QFrame.StyledPanel)

        # Create tools to interact with the list widget: expand or collapse -
        # add a list item - remove a list item
        tool_widget = QtGui.QWidget(parent)
        layout = QtGui.QHBoxLayout()
        layout.addStretch(1)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(2)
        tool_widget.setLayout(layout)
        # Create the tool buttons
        resize_button = QtGui.QToolButton()
        layout.addWidget(resize_button)
        # Set the tool icons
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/nav_down")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        resize_button.setIcon(icon)
        resize_button.setFixedSize(30, 22)

        editable_labels = False
        if trait.handler.inner_traits():
            editable_labels = True
            frame.inner_trait = trait.handler.inner_traits()[0]

            add_button = QtGui.QToolButton()
            delete_button = QtGui.QToolButton()
            layout.addWidget(add_button)
            # Set the tool icons
            icon = QtGui.QIcon()
            icon.addPixmap(
                QtGui.QPixmap(_fromUtf8(":/soma_widgets_icons/add")),
                QtGui.QIcon.Normal, QtGui.QIcon.Off)
            add_button.setIcon(icon)
            add_button.setFixedSize(30, 22)
            delete_button.setFixedSize(30, 22)
            # Add list item callback
            add_hook = partial(ControllerControlWidget.add_item,
                               weak_proxy(parent), control_name,
                               weak_proxy(frame))
            add_button.clicked.connect(add_hook)

        # Create the associated controller widget
        controller_widget = ControllerWidget(control_value,
                                             parent=frame,
                                             live=True,
                                             editable_labels=editable_labels)

        # Store some parameters in the list widget
        frame.trait = trait
        frame.controller = control_value
        frame.controller_widget = controller_widget
        frame.connected = False

        # Add the list controller widget to the list widget
        frame.setLayout(controller_widget.layout())

        # Set some callback on the controller control tools
        # Resize callback
        resize_hook = partial(ControllerControlWidget.expand_or_collapse,
                              weak_proxy(frame), weak_proxy(resize_button))
        resize_button.clicked.connect(resize_hook)

        if getattr(trait, 'expanded') is False:
            ControllerControlWidget.set_expanded(frame, resize_button, False)

        # Create the label associated with the controller widget
        control_label = trait.label
        if control_label is None:
            control_label = control_name
        if label_class is None:
            label_class = QtGui.QLabel
        if control_label is not None:
            label = label_class(control_label, parent)
        else:
            label = None

        return (frame, (label, tool_widget))
예제 #12
0
    def __init__(self,
                 attributed_process,
                 enable_attr_from_filename=False,
                 enable_load_buttons=False):
        """
        Parameters
        ----------
        attributed_process: Process instance
            process with attributes to be displayed
        enable_attr_from_filename: bool (optional)
            if enabled, it will be possible to specify an input filename to
            build attributes from
        """
        super(AttributedProcessWidget, self).__init__()
        self.setLayout(QtGui.QVBoxLayout())
        self.attributed_process = attributed_process
        self._show_completion = False

        process = attributed_process
        completion_engine = getattr(process, 'completion_engine', None)

        if completion_engine is not None:
            splitter = QtGui.QSplitter(QtCore.Qt.Vertical)
            self.layout().addWidget(splitter)
            spl_up = QtGui.QWidget()
            spl_up.setLayout(QtGui.QVBoxLayout())
            splitter.addWidget(spl_up)
            spl_down = QtGui.QWidget()
            spl_down.setLayout(QtGui.QVBoxLayout())
            splitter.addWidget(spl_down)
        else:
            spl_up = self
            spl_down = self

        if enable_attr_from_filename and completion_engine is not None:
            c = Controller()
            c.add_trait('attributes_from_input_filename', File(optional=True))
            cw = ControllerWidget(c, live=True)
            spl_up.layout().addWidget(cw)
            self.input_filename_controller = c
            c.on_trait_change(self.on_input_filename_changed,
                              'attributes_from_input_filename',
                              dispatch='ui')
            cw.setSizePolicy(QtGui.QSizePolicy.Expanding,
                             QtGui.QSizePolicy.Fixed)

        # groupbox area to show attributs
        attrib_widget = QtGui.QGroupBox('Attributes:')
        attrib_widget.setAlignment(QtCore.Qt.AlignLeft)
        attrib_widget.setLayout(QtGui.QVBoxLayout())
        self.attrib_widget = attrib_widget
        spl_up.layout().addWidget(attrib_widget)
        attrib_widget.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                    QtGui.QSizePolicy.Preferred)

        hlay = QtGui.QHBoxLayout()
        spl_up.layout().addLayout(hlay)
        # CheckBox to completion rules or not
        self.checkbox_fom = QtGui.QCheckBox('Follow completion rules')
        self.checkbox_fom.setChecked(True)
        self.checkbox_fom.stateChanged.connect(self.on_use_fom_change)
        hlay.addWidget(self.checkbox_fom)

        # Button Show/Hide completion
        self.btn_show_completion = QtGui.QCheckBox('Show completion')
        self.btn_show_completion.setSizePolicy(QtGui.QSizePolicy.Fixed,
                                               QtGui.QSizePolicy.Fixed)
        hlay.addWidget(self.btn_show_completion)
        self.btn_show_completion.stateChanged.connect(self.on_show_completion)

        # groupbox area to show completion
        param_widget = QtGui.QGroupBox('Parameters:')
        param_widget.setAlignment(QtCore.Qt.AlignLeft)
        spl_down.layout().addWidget(param_widget)
        param_widget.setLayout(QtGui.QVBoxLayout())
        param_widget.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        # Create controller widget for process and object_attribute
        self.controller_widget = ScrollControllerWidget(process,
                                                        live=True,
                                                        parent=param_widget)

        if completion_engine is not None:
            self.controller_widget2 = ScrollControllerWidget(
                completion_engine.get_attribute_values(),
                live=True,
                parent=attrib_widget)
            completion_engine.get_attribute_values().on_trait_change(
                completion_engine.attributes_changed, 'anytrait')
        else:
            self.controller_widget2 = ScrollControllerWidget(Controller())

        # Set controller of attributs and controller of process for each
        # corresponding area
        param_widget.layout().addWidget(self.controller_widget)
        attrib_widget.layout().addWidget(self.controller_widget2)

        if enable_load_buttons and completion_engine is not None:
            io_lay = QtGui.QHBoxLayout()
            self.layout().addLayout(io_lay)
            self.btn_load_json = QtGui.QPushButton('Load attributes')
            io_lay.addWidget(self.btn_load_json)
            self.btn_load_json.clicked.connect(self.on_btn_load_json)
            self.btn_save_json = QtGui.QPushButton('Save attributes')
            io_lay.addWidget(self.btn_save_json)
            self.btn_save_json.clicked.connect(self.on_btn_save_json)

        if completion_engine is None:
            attrib_widget.hide()
            self.checkbox_fom.hide()
            self.btn_show_completion.hide()
            self.show_completion(True)  # hide file parts
        else:
            self.show_completion(False)  # hide file parts

        if completion_engine is not None:
            completion_engine.on_trait_change(
                self._completion_progress_changed,
                'completion_progress',
                dispatch='ui')