Exemple #1
0
    def __init__(self, group, ui, suppress_label=False):
        """Initialise the object.
        """
        # Get the contents of the group:
        content = group.get_content()

        # Save these for other methods.
        self.group = group
        self.ui = ui

        if group.orientation == 'horizontal':
            self.direction = QtGui.QBoxLayout.LeftToRight
        else:
            self.direction = QtGui.QBoxLayout.TopToBottom

        # outer is the top-level widget or layout that will eventually be
        # returned.  sub is the QTabWidget or QToolBox corresponding to any
        # 'tabbed' or 'fold' layout.  It is only used to collapse nested
        # widgets.  inner is the object (not necessarily a layout) that new
        # controls should be added to.
        outer = sub = inner = None

        # Get the group label.
        if suppress_label:
            label = ""
        else:
            label = group.label

        # Create a border if requested.
        if group.show_border:
            outer = QtGui.QGroupBox(label)
            inner = QtGui.QBoxLayout(self.direction, outer)

        elif label != "":
            outer = inner = QtGui.QBoxLayout(self.direction)
            inner.addWidget(ui_panel.heading_text(None, text=label).control)

        # Add the layout specific content.
        if len(content) == 0:
            pass

        elif group.layout == 'flow':
            raise NotImplementedError, "'the 'flow' layout isn't implemented"

        elif group.layout == 'split':
            # Create the splitter.
            splitter = ui_panel._GroupSplitter(group)
            splitter.setOpaqueResize(False)  # Mimic wx backend resize behavior
            if self.direction == QtGui.QBoxLayout.TopToBottom:
                splitter.setOrientation(QtCore.Qt.Vertical)

            # Make sure the splitter will expand to fill available space
            policy = splitter.sizePolicy()
            policy.setHorizontalStretch(50)
            policy.setVerticalStretch(50)
            if group.orientation == 'horizontal':
                policy.setVerticalPolicy(QtGui.QSizePolicy.Expanding)
            else:
                policy.setHorizontalPolicy(QtGui.QSizePolicy.Expanding)
            splitter.setSizePolicy(policy)

            if outer is None:
                outer = splitter
            else:
                inner.addWidget(splitter)

            # Create an editor.
            editor = ui_panel.SplitterGroupEditor(control=outer, splitter=splitter, ui=ui)
            self._setup_editor(group, editor)

            self._add_splitter_items(content, splitter)

        elif group.layout in ('tabbed', 'fold'):
            # Create the TabWidget or ToolBox.
            if group.layout == 'tabbed':
                sub = QtGui.QTabWidget()
                sub.setProperty("traits_tabbed_group", True)
            else:
                sub = QtGui.QToolBox()

            # Give tab/tool widget stretch factor equivalent to default stretch
            # factory for a resizeable item. See end of '_add_items'.
            policy = sub.sizePolicy()
            policy.setHorizontalStretch(50)
            policy.setVerticalStretch(50)
            sub.setSizePolicy(policy)

            ui_panel._fill_panel(sub, content, self.ui, self._add_page_item)

            if outer is None:
                outer = sub
            else:
                inner.addWidget(sub)

            # Create an editor.
            editor = ui_panel.TabbedFoldGroupEditor(container=sub, control=outer, ui=ui)
            self._setup_editor(group, editor)

        else:
            # See if we need to control the visual appearance of the group.
            if group.visible_when != '' or group.enabled_when != '':
                # Make sure that outer is a widget and inner is a layout.
                # Hiding a layout is not properly supported by Qt (the
                # workaround in ``traitsui.qt4.editor._visible_changed_helper``
                # often leaves undesirable blank space).
                if outer is None:
                    outer = inner = QtGui.QBoxLayout(self.direction)

                if isinstance(outer, QtGui.QLayout):
                    widget = QtGui.QWidget()
                    widget.setLayout(outer)
                    outer = widget

                # Create an editor.
                self._setup_editor(group, ui_panel.GroupEditor(control=outer))

            if isinstance(content[0], Group):
                layout = self._add_groups(content, inner)
            else:
                layout = self._add_items(content, inner)
            layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)

            if outer is None:
                outer = layout
            elif layout is not inner:
                inner.addLayout(layout)

        if group.style_sheet:
            if isinstance(outer, QtGui.QLayout):
                inner = outer
                outer = QtGui.QWidget()
                outer.setLayout(inner)

            # ensure this is not empty group
            if isinstance(outer, QtGui.QWidget):
                outer.setStyleSheet(group.style_sheet)

        # Publish the top-level widget, layout or None.
        self.control = outer

        # Publish the optional sub-control.
        self.sub_control = sub
Exemple #2
0
    def _add_items(self, content, outer=None):
        """Adds a list of Item objects, creating a layout if needed.  Return
           the outermost layout.
        """
        # Get local references to various objects we need:
        ui = self.ui
        info = ui.info
        handler = ui.handler

        group = self.group
        show_left = group.show_left
        columns = group.columns

        # See if a label is needed.
        show_labels = False
        for item in content:
            show_labels |= item.show_label

        # See if a grid layout is needed.
        if show_labels or columns > 1:
            inner = QtGui.QGridLayout()

            if outer is None:
                outer = inner
            else:
                outer.addLayout(inner)

            row = 0
            if show_left:
                label_alignment = QtCore.Qt.AlignRight
            else:
                label_alignment = QtCore.Qt.AlignLeft

        else:
            # Use the existing layout if there is one.
            if outer is None:
                outer = QtGui.QBoxLayout(self.direction)

            inner = outer

            row = -1
            label_alignment = 0

        # Process each Item in the list:
        col = -1
        for item in content:

            # Keep a track of the current logical row and column unless the
            # layout is not a grid.
            col += 1
            if row >= 0 and col >= columns:
                col = 0
                row += 1

            # Get the name in order to determine its type:
            name = item.name

            # Check if is a label:
            if name == '':
                label = item.label
                if label != "":

                    # Create the label widget.
                    if item.style == 'simple':
                        label = QtGui.QLabel(label)
                    else:
                        label = ui_panel.heading_text(None, text=label).control

                    self._add_widget(inner, label, row, col, show_labels)

                    if item.emphasized:
                        self._add_emphasis(label)

                # Continue on to the next Item in the list:
                continue

            # Check if it is a separator:
            if name == '_':
                cols = columns

                # See if the layout is a grid.
                if row >= 0:
                    # Move to the start of the next row if necessary.
                    if col > 0:
                        col = 0
                        row += 1

                    # Skip the row we are about to do.
                    row += 1

                    # Allow for the columns.
                    if show_labels:
                        cols *= 2

                for i in range(cols):
                    line = QtGui.QFrame()

                    if self.direction == QtGui.QBoxLayout.LeftToRight:
                        # Add a vertical separator:
                        line.setFrameShape(QtGui.QFrame.VLine)
                        if row < 0:
                            inner.addWidget(line)
                        else:
                            inner.addWidget(line, i, row)
                    else:
                        # Add a horizontal separator:
                        line.setFrameShape(QtGui.QFrame.HLine)
                        if row < 0:
                            inner.addWidget(line)
                        else:
                            inner.addWidget(line, row, i)

                    line.setFrameShadow(QtGui.QFrame.Sunken)

                # Continue on to the next Item in the list:
                continue

            # Convert a blank to a 5 pixel spacer:
            if name == ' ':
                name = '5'

            # Check if it is a spacer:
            if ui_panel.all_digits.match(name):

                # If so, add the appropriate amount of space to the layout:
                n = int(name)
                if self.direction == QtGui.QBoxLayout.LeftToRight:
                    # Add a horizontal spacer:
                    spacer = QtGui.QSpacerItem(n, 1)
                else:
                    # Add a vertical spacer:
                    spacer = QtGui.QSpacerItem(1, n)

                self._add_widget(inner, spacer, row, col, show_labels)

                # Continue on to the next Item in the list:
                continue

            # Otherwise, it must be a trait Item:
            object = eval(item.object_, globals(), ui.context)
            trait = object.base_trait(name)
            desc = trait.desc or ''

            # Get the editor factory associated with the Item:
            editor_factory = item.editor
            if editor_factory is None:
                editor_factory = trait.get_editor().set(**item.editor_args)

                # If still no editor factory found, use a default text editor:
                if editor_factory is None:
                    from traitsui.qt4.text_editor import ToolkitEditorFactory

                    editor_factory = ToolkitEditorFactory()

                # If the item has formatting traits set them in the editor
                # factory:
                if item.format_func is not None:
                    editor_factory.format_func = item.format_func

                if item.format_str != '':
                    editor_factory.format_str = item.format_str

                # If the item has an invalid state extended trait name, set it
                # in the editor factory:
                if item.invalid != '':
                    editor_factory.invalid = item.invalid

            # Create the requested type of editor from the editor factory:
            factory_method = getattr(editor_factory, item.style + '_editor')
            editor = factory_method(
                ui, object, name, item.tooltip, None
            ).set(item=item, object_name=item.object)

            # Tell the editor to actually build the editing widget.  Note that
            # "inner" is a layout.  This shouldn't matter as individual editors
            # shouldn't be using it as a parent anyway.  The important thing is
            # that it is not None (otherwise the main TraitsUI code can change
            # the "kind" of the created UI object).
            editor.prepare(inner)
            control = editor.control

            if item.style_sheet:
                control.setStyleSheet(item.style_sheet)

            # Set the initial 'enabled' state of the editor from the factory:
            editor.enabled = editor_factory.enabled

            # Handle any label.
            if item.show_label:
                label = self._create_label(item, ui, desc)
                self._add_widget(inner, label, row, col, show_labels,
                                 label_alignment)
            else:
                label = None

            editor.label_control = label

            # Add emphasis to the editor control if requested:
            if item.emphasized:
                self._add_emphasis(control)

            # Give the editor focus if it requested it:
            if item.has_focus:
                control.setFocus()

            # Set the correct size on the control, as specified by the user:
            stretch = 0
            item_width = item.width
            item_height = item.height
            if (item_width != -1) or (item_height != -1):
                is_horizontal = (self.direction == QtGui.QBoxLayout.LeftToRight)

                min_size = control.minimumSizeHint()
                width = min_size.width()
                height = min_size.height()

                force_width = False
                force_height = False

                if (0.0 < item_width <= 1.0) and is_horizontal:
                    stretch = int(100 * item_width)

                item_width = int(item_width)
                if item_width < -1:
                    item_width = -item_width
                    force_width = True
                else:
                    item_width = max(item_width, width)

                if (0.0 < item_height <= 1.0) and (not is_horizontal):
                    stretch = int(100 * item_height)

                item_height = int(item_height)
                if item_height < -1:
                    item_height = -item_height
                    force_height = True
                else:
                    item_height = max(item_height, height)

                control.setMinimumWidth(max(item_width, 0))
                control.setMinimumHeight(max(item_height, 0))
                if (stretch == 0 or not is_horizontal) and force_width:
                    control.setMaximumWidth(item_width)
                if (stretch == 0 or is_horizontal) and force_height:
                    control.setMaximumHeight(item_height)

            # Set size and stretch policies
            self._set_item_size_policy(editor, item, label, stretch)

            # Add the created editor control to the layout
            # FIXME: Need to decide what to do about border_size and padding
            self._add_widget(inner, control, row, col, show_labels)

            # ---- Update the UI object

            # Bind the editor into the UIInfo object name space so it can be
            # referred to by a Handler while the user interface is active:
            id = item.id or name
            info.bind(id, editor, item.id)

            self.ui._scrollable |= editor.scrollable

            # Also, add the editors to the list of editors used to construct
            # the user interface:
            ui._editors.append(editor)

            # If the handler wants to be notified when the editor is created,
            # add it to the list of methods to be called when the UI is
            # complete:
            defined = getattr(handler, id + '_defined', None)
            if defined is not None:
                ui.add_defined(defined)

            # If the editor is conditionally visible, add the visibility
            # 'expression' and the editor to the UI object's list of monitored
            # objects:
            if item.visible_when != '':
                ui.add_visible(item.visible_when, editor)

            # If the editor is conditionally enabled, add the enabling
            # 'expression' and the editor to the UI object's list of monitored
            # objects:
            if item.enabled_when != '':
                ui.add_enabled(item.enabled_when, editor)

        return outer
Exemple #3
0
    def __init__(self, group, ui, suppress_label=False):
        """Initialise the object.
        """
        # Get the contents of the group:
        content = group.get_content()

        # Save these for other methods.
        self.group = group
        self.ui = ui

        if group.orientation == "horizontal":
            self.direction = QtGui.QBoxLayout.LeftToRight
        else:
            self.direction = QtGui.QBoxLayout.TopToBottom

        # outer is the top-level widget or layout that will eventually be
        # returned.  sub is the QTabWidget or QToolBox corresponding to any
        # 'tabbed' or 'fold' layout.  It is only used to collapse nested
        # widgets.  inner is the object (not necessarily a layout) that new
        # controls should be added to.
        outer = sub = inner = None

        # Get the group label.
        if suppress_label:
            label = ""
        else:
            label = group.label

        # Create a border if requested.
        if group.show_border:
            outer = QtGui.QGroupBox(label)
            inner = QtGui.QBoxLayout(self.direction, outer)

        elif label != "":
            outer = inner = QtGui.QBoxLayout(self.direction)
            inner.addWidget(ui_panel.heading_text(None, text=label).control)

        # Add the layout specific content.
        if len(content) == 0:
            pass

        elif group.layout == "flow":
            raise NotImplementedError, "'the 'flow' layout isn't implemented"

        elif group.layout == "split":
            # Create the splitter.
            splitter = ui_panel._GroupSplitter(group)
            splitter.setOpaqueResize(False)  # Mimic wx backend resize behavior
            if self.direction == QtGui.QBoxLayout.TopToBottom:
                splitter.setOrientation(QtCore.Qt.Vertical)

            # Make sure the splitter will expand to fill available space
            policy = splitter.sizePolicy()
            policy.setHorizontalStretch(50)
            policy.setVerticalStretch(50)
            if group.orientation == "horizontal":
                policy.setVerticalPolicy(QtGui.QSizePolicy.Expanding)
            else:
                policy.setHorizontalPolicy(QtGui.QSizePolicy.Expanding)
            splitter.setSizePolicy(policy)

            if outer is None:
                outer = splitter
            else:
                inner.addWidget(splitter)

            # Create an editor.
            editor = ui_panel.SplitterGroupEditor(control=outer, splitter=splitter, ui=ui)
            self._setup_editor(group, editor)

            self._add_splitter_items(content, splitter)

        elif group.layout in ("tabbed", "fold"):
            # Create the TabWidget or ToolBox.
            if group.layout == "tabbed":
                sub = QtGui.QTabWidget()
                sub.setProperty("traits_tabbed_group", True)
            else:
                sub = QtGui.QToolBox()

            # Give tab/tool widget stretch factor equivalent to default stretch
            # factory for a resizeable item. See end of '_add_items'.
            policy = sub.sizePolicy()
            policy.setHorizontalStretch(50)
            policy.setVerticalStretch(50)
            sub.setSizePolicy(policy)

            ui_panel._fill_panel(sub, content, self.ui, self._add_page_item)

            if outer is None:
                outer = sub
            else:
                inner.addWidget(sub)

            # Create an editor.
            editor = ui_panel.TabbedFoldGroupEditor(container=sub, control=outer, ui=ui)
            self._setup_editor(group, editor)

        else:
            # See if we need to control the visual appearance of the group.
            if group.visible_when != "" or group.enabled_when != "":
                # Make sure that outer is a widget and inner is a layout.
                # Hiding a layout is not properly supported by Qt (the
                # workaround in ``traitsui.qt4.editor._visible_changed_helper``
                # often leaves undesirable blank space).
                if outer is None:
                    outer = inner = QtGui.QBoxLayout(self.direction)

                if isinstance(outer, QtGui.QLayout):
                    widget = QtGui.QWidget()
                    widget.setLayout(outer)
                    outer = widget

                # Create an editor.
                self._setup_editor(group, ui_panel.GroupEditor(control=outer))

            if isinstance(content[0], Group):
                layout = self._add_groups(content, inner)
            else:
                layout = self._add_items(content, inner)
            layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)

            if outer is None:
                outer = layout
            elif layout is not inner:
                inner.addLayout(layout)

        if group.style_sheet:
            if isinstance(outer, QtGui.QLayout):
                inner = outer
                outer = QtGui.QWidget()
                outer.setLayout(inner)

            # ensure this is not empty group
            if isinstance(outer, QtGui.QWidget):
                outer.setStyleSheet(group.style_sheet)

        # Publish the top-level widget, layout or None.
        self.control = outer

        # Publish the optional sub-control.
        self.sub_control = sub
Exemple #4
0
    def _add_items(self, content, outer=None):
        """Adds a list of Item objects, creating a layout if needed.  Return
           the outermost layout.
        """
        # Get local references to various objects we need:
        ui = self.ui
        info = ui.info
        handler = ui.handler

        group = self.group
        show_left = group.show_left
        columns = group.columns

        # See if a label is needed.
        show_labels = False
        for item in content:
            show_labels |= item.show_label

        # See if a grid layout is needed.
        if show_labels or columns > 1:
            inner = QtGui.QGridLayout()

            if outer is None:
                outer = inner
            else:
                outer.addLayout(inner)

            row = 0
            if show_left:
                label_alignment = QtCore.Qt.AlignRight
            else:
                label_alignment = QtCore.Qt.AlignLeft

        else:
            # Use the existing layout if there is one.
            if outer is None:
                outer = QtGui.QBoxLayout(self.direction)

            inner = outer

            row = -1
            label_alignment = 0

        # Process each Item in the list:
        col = -1
        for item in content:

            # Keep a track of the current logical row and column unless the
            # layout is not a grid.
            col += 1
            if row >= 0 and col >= columns:
                col = 0
                row += 1

            # Get the name in order to determine its type:
            name = item.name

            # Check if is a label:
            if name == "":
                label = item.label
                if label != "":

                    # Create the label widget.
                    if item.style == "simple":
                        label = QtGui.QLabel(label)
                    else:
                        label = ui_panel.heading_text(None, text=label).control

                    self._add_widget(inner, label, row, col, show_labels)

                    if item.emphasized:
                        self._add_emphasis(label)

                # Continue on to the next Item in the list:
                continue

            # Check if it is a separator:
            if name == "_":
                cols = columns

                # See if the layout is a grid.
                if row >= 0:
                    # Move to the start of the next row if necessary.
                    if col > 0:
                        col = 0
                        row += 1

                    # Skip the row we are about to do.
                    row += 1

                    # Allow for the columns.
                    if show_labels:
                        cols *= 2

                for i in range(cols):
                    line = QtGui.QFrame()

                    if self.direction == QtGui.QBoxLayout.LeftToRight:
                        # Add a vertical separator:
                        line.setFrameShape(QtGui.QFrame.VLine)
                        if row < 0:
                            inner.addWidget(line)
                        else:
                            inner.addWidget(line, i, row)
                    else:
                        # Add a horizontal separator:
                        line.setFrameShape(QtGui.QFrame.HLine)
                        if row < 0:
                            inner.addWidget(line)
                        else:
                            inner.addWidget(line, row, i)

                    line.setFrameShadow(QtGui.QFrame.Sunken)

                # Continue on to the next Item in the list:
                continue

            # Convert a blank to a 5 pixel spacer:
            if name == " ":
                name = "5"

            # Check if it is a spacer:
            if ui_panel.all_digits.match(name):

                # If so, add the appropriate amount of space to the layout:
                n = int(name)
                if self.direction == QtGui.QBoxLayout.LeftToRight:
                    # Add a horizontal spacer:
                    spacer = QtGui.QSpacerItem(n, 1)
                else:
                    # Add a vertical spacer:
                    spacer = QtGui.QSpacerItem(1, n)

                self._add_widget(inner, spacer, row, col, show_labels)

                # Continue on to the next Item in the list:
                continue

            # Otherwise, it must be a trait Item:
            object = eval(item.object_, globals(), ui.context)
            trait = object.base_trait(name)
            desc = trait.desc or ""

            # Get the editor factory associated with the Item:
            editor_factory = item.editor
            if editor_factory is None:
                editor_factory = trait.get_editor().set(**item.editor_args)

                # If still no editor factory found, use a default text editor:
                if editor_factory is None:
                    from traitsui.qt4.text_editor import ToolkitEditorFactory

                    editor_factory = ToolkitEditorFactory()

                # If the item has formatting traits set them in the editor
                # factory:
                if item.format_func is not None:
                    editor_factory.format_func = item.format_func

                if item.format_str != "":
                    editor_factory.format_str = item.format_str

                # If the item has an invalid state extended trait name, set it
                # in the editor factory:
                if item.invalid != "":
                    editor_factory.invalid = item.invalid

            # Create the requested type of editor from the editor factory:
            factory_method = getattr(editor_factory, item.style + "_editor")
            editor = factory_method(ui, object, name, item.tooltip, None).set(item=item, object_name=item.object)

            # Tell the editor to actually build the editing widget.  Note that
            # "inner" is a layout.  This shouldn't matter as individual editors
            # shouldn't be using it as a parent anyway.  The important thing is
            # that it is not None (otherwise the main TraitsUI code can change
            # the "kind" of the created UI object).
            editor.prepare(inner)
            control = editor.control

            if item.style_sheet:
                control.setStyleSheet(item.style_sheet)

            # Set the initial 'enabled' state of the editor from the factory:
            editor.enabled = editor_factory.enabled

            # Handle any label.
            if item.show_label:
                label = self._create_label(item, ui, desc)
                self._add_widget(inner, label, row, col, show_labels, label_alignment)
            else:
                label = None

            editor.label_control = label

            # Add emphasis to the editor control if requested:
            if item.emphasized:
                self._add_emphasis(control)

            # Give the editor focus if it requested it:
            if item.has_focus:
                control.setFocus()

            # Set the correct size on the control, as specified by the user:
            stretch = 0
            item_width = item.width
            item_height = item.height
            if (item_width != -1) or (item_height != -1):
                is_horizontal = self.direction == QtGui.QBoxLayout.LeftToRight

                min_size = control.minimumSizeHint()
                width = min_size.width()
                height = min_size.height()

                force_width = False
                force_height = False

                if (0.0 < item_width <= 1.0) and is_horizontal:
                    stretch = int(100 * item_width)

                item_width = int(item_width)
                if item_width < -1:
                    item_width = -item_width
                    force_width = True
                else:
                    item_width = max(item_width, width)

                if (0.0 < item_height <= 1.0) and (not is_horizontal):
                    stretch = int(100 * item_height)

                item_height = int(item_height)
                if item_height < -1:
                    item_height = -item_height
                    force_height = True
                else:
                    item_height = max(item_height, height)

                control.setMinimumWidth(max(item_width, 0))
                control.setMinimumHeight(max(item_height, 0))
                if (stretch == 0 or not is_horizontal) and force_width:
                    control.setMaximumWidth(item_width)
                if (stretch == 0 or is_horizontal) and force_height:
                    control.setMaximumHeight(item_height)

            # Set size and stretch policies
            self._set_item_size_policy(editor, item, label, stretch)

            # Add the created editor control to the layout
            # FIXME: Need to decide what to do about border_size and padding
            self._add_widget(inner, control, row, col, show_labels)

            # ---- Update the UI object

            # Bind the editor into the UIInfo object name space so it can be
            # referred to by a Handler while the user interface is active:
            id = item.id or name
            info.bind(id, editor, item.id)

            self.ui._scrollable |= editor.scrollable

            # Also, add the editors to the list of editors used to construct
            # the user interface:
            ui._editors.append(editor)

            # If the handler wants to be notified when the editor is created,
            # add it to the list of methods to be called when the UI is
            # complete:
            defined = getattr(handler, id + "_defined", None)
            if defined is not None:
                ui.add_defined(defined)

            # If the editor is conditionally visible, add the visibility
            # 'expression' and the editor to the UI object's list of monitored
            # objects:
            if item.visible_when != "":
                ui.add_visible(item.visible_when, editor)

            # If the editor is conditionally enabled, add the enabling
            # 'expression' and the editor to the UI object's list of monitored
            # objects:
            if item.enabled_when != "":
                ui.add_enabled(item.enabled_when, editor)

        return outer
Exemple #5
0
    def __init__(self, ui, parent, is_subpanel):
        """Initialise the object.
        """
        self.ui = ui
        history = ui.history
        view = ui.view

        # Reset any existing history listeners.
        if history is not None:
            history.on_trait_change(self._on_undoable, 'undoable', remove=True)
            history.on_trait_change(self._on_redoable, 'redoable', remove=True)
            history.on_trait_change(self._on_revertable,
                                    'undoable',
                                    remove=True)

        # Determine if we need any buttons or an 'undo' history.
        buttons = [self.coerce_button(button) for button in view.buttons]
        nr_buttons = len(buttons)
        has_buttons = (not is_subpanel and
                       (nr_buttons != 1 or not self.is_button(buttons[0], '')))

        if nr_buttons == 0:
            if view.undo:
                self.check_button(buttons, UndoButton)
            if view.revert:
                self.check_button(buttons, RevertButton)
            if view.help:
                self.check_button(buttons, HelpButton)

        if not is_subpanel and history is None:
            for button in buttons:
                if self.is_button(button, 'Undo') or self.is_button(
                        button, 'Revert'):
                    history = ui.history = UndoHistory()
                    break

        # Create the panel.
        self.control = panel(ui)
        # if self.control.isinstance(QtGui.QTabWidget):
        #     self.control.setTabBar(myQTabBar())

        # Suppress the title if this is a subpanel or if we think it should be
        # superceded by the title of an "outer" widget (eg. a dock widget).
        title = view.title
        if (is_subpanel or (isinstance(parent, QtGui.QMainWindow)
                            and not isinstance(parent.parent(), QtGui.QDialog))
                or isinstance(parent, QtGui.QTabWidget)):
            title = ""

        # ============ Monkey Patch ===============
        if isinstance(parent, QtGui.QTabWidget):
            bar = parent.tabBar()
            if not isinstance(bar, myQTabBar):
                parent.setTabBar(myQTabBar())
        # =========================================

        # Panels must be widgets as it is only the TraitsUI PyQt code that can
        # handle them being layouts as well.  Therefore create a widget if the
        # panel is not a widget or if we need a title or buttons.
        if not isinstance(self.control,
                          QtGui.QWidget) or title != "" or has_buttons:
            w = QtGui.QWidget()
            layout = QtGui.QVBoxLayout(w)
            layout.setContentsMargins(0, 0, 0, 0)

            # Handle any view title.
            if title != "":
                layout.addWidget(heading_text(None, text=view.title).control)

            if isinstance(self.control, QtGui.QWidget):
                layout.addWidget(self.control)
            elif isinstance(self.control, QtGui.QLayout):
                layout.addLayout(self.control)

            self.control = w

            # Add any buttons.
            if has_buttons:

                # Add the horizontal separator
                separator = QtGui.QFrame()
                separator.setFrameStyle(QtGui.QFrame.Sunken
                                        | QtGui.QFrame.HLine)
                separator.setFixedHeight(2)
                layout.addWidget(separator)

                # Add the special function buttons
                bbox = QtGui.QDialogButtonBox(QtCore.Qt.Horizontal)
                for button in buttons:
                    role = QtGui.QDialogButtonBox.ActionRole
                    if self.is_button(button, 'Undo'):
                        self.undo = self.add_button(button, bbox, role,
                                                    self._on_undo, False,
                                                    'Undo')
                        self.redo = self.add_button(button, bbox, role,
                                                    self._on_redo, False,
                                                    'Redo')
                        history.on_trait_change(self._on_undoable,
                                                'undoable',
                                                dispatch='ui')
                        history.on_trait_change(self._on_redoable,
                                                'redoable',
                                                dispatch='ui')
                    elif self.is_button(button, 'Revert'):
                        role = QtGui.QDialogButtonBox.ResetRole
                        self.revert = self.add_button(button, bbox, role,
                                                      self._on_revert, False)
                        history.on_trait_change(self._on_revertable,
                                                'undoable',
                                                dispatch='ui')
                    elif self.is_button(button, 'Help'):
                        role = QtGui.QDialogButtonBox.HelpRole
                        self.add_button(button, bbox, role, self._on_help)
                    elif not self.is_button(button, ''):
                        self.add_button(button, bbox, role)
                layout.addWidget(bbox)

        # Ensure the control has a size hint reflecting the View specification.
        # Yes, this is a hack, but it's too late to repair this convoluted
        # control building process, so we do what we have to...
        self.control.sizeHint = _size_hint_wrapper(self.control.sizeHint, ui)
Exemple #6
0
    def __init__(self, ui, parent, is_subpanel):
        """Initialise the object.
        """
        self.ui = ui
        history = ui.history
        view = ui.view

        # Reset any existing history listeners.
        if history is not None:
            history.on_trait_change(self._on_undoable, 'undoable', remove=True)
            history.on_trait_change(self._on_redoable, 'redoable', remove=True)
            history.on_trait_change(self._on_revertable, 'undoable',
                                    remove=True)

        # Determine if we need any buttons or an 'undo' history.
        buttons = [self.coerce_button(button) for button in view.buttons]
        nr_buttons = len(buttons)
        has_buttons = (not is_subpanel and (nr_buttons != 1 or
                                            not self.is_button(buttons[0], '')))

        if nr_buttons == 0:
            if view.undo:
                self.check_button(buttons, UndoButton)
            if view.revert:
                self.check_button(buttons, RevertButton)
            if view.help:
                self.check_button(buttons, HelpButton)

        if not is_subpanel and history is None:
            for button in buttons:
                if self.is_button(button, 'Undo') or self.is_button(button, 'Revert'):
                    history = ui.history = UndoHistory()
                    break

        # Create the panel.
        self.control = panel(ui)
        # if self.control.isinstance(QtGui.QTabWidget):
        #     self.control.setTabBar(myQTabBar())

        # Suppress the title if this is a subpanel or if we think it should be
        # superceded by the title of an "outer" widget (eg. a dock widget).
        title = view.title
        if (is_subpanel or (isinstance(parent, QtGui.QMainWindow) and
                                not isinstance(parent.parent(), QtGui.QDialog)) or
                isinstance(parent, QtGui.QTabWidget)):
            title = ""

        # ============ Monkey Patch ===============
        if isinstance(parent, QtGui.QTabWidget):
            bar = parent.tabBar()
            if not isinstance(bar, myQTabBar):
                parent.setTabBar(myQTabBar())

        # p = parent
        # while p is not None:
        #     try:
        #         bar = p.tabBar()
        #     except AttributeError:
        #         bar = None
        #     print p, bar
        #     p = p.parent()
        # =========================================

        # Panels must be widgets as it is only the TraitsUI PyQt code that can
        # handle them being layouts as well.  Therefore create a widget if the
        # panel is not a widget or if we need a title or buttons.
        if not isinstance(self.control, QtGui.QWidget) or title != "" or has_buttons:
            w = QtGui.QWidget()
            layout = QtGui.QVBoxLayout(w)
            layout.setContentsMargins(0, 0, 0, 0)

            # Handle any view title.
            if title != "":
                layout.addWidget(heading_text(None, text=view.title).control)

            if isinstance(self.control, QtGui.QWidget):
                layout.addWidget(self.control)
            elif isinstance(self.control, QtGui.QLayout):
                layout.addLayout(self.control)

            self.control = w

            # Add any buttons.
            if has_buttons:

                # Add the horizontal separator
                separator = QtGui.QFrame()
                separator.setFrameStyle(QtGui.QFrame.Sunken |
                                        QtGui.QFrame.HLine)
                separator.setFixedHeight(2)
                layout.addWidget(separator)

                # Add the special function buttons
                bbox = QtGui.QDialogButtonBox(QtCore.Qt.Horizontal)
                for button in buttons:
                    role = QtGui.QDialogButtonBox.ActionRole
                    if self.is_button(button, 'Undo'):
                        self.undo = self.add_button(button, bbox, role,
                                                    self._on_undo, False,
                                                    'Undo')
                        self.redo = self.add_button(button, bbox, role,
                                                    self._on_redo, False,
                                                    'Redo')
                        history.on_trait_change(self._on_undoable, 'undoable',
                                                dispatch='ui')
                        history.on_trait_change(self._on_redoable, 'redoable',
                                                dispatch='ui')
                    elif self.is_button(button, 'Revert'):
                        role = QtGui.QDialogButtonBox.ResetRole
                        self.revert = self.add_button(button, bbox, role,
                                                      self._on_revert, False)
                        history.on_trait_change(self._on_revertable, 'undoable',
                                                dispatch='ui')
                    elif self.is_button(button, 'Help'):
                        role = QtGui.QDialogButtonBox.HelpRole
                        self.add_button(button, bbox, role, self._on_help)
                    elif not self.is_button(button, ''):
                        self.add_button(button, bbox, role)
                layout.addWidget(bbox)

        # Ensure the control has a size hint reflecting the View specification.
        # Yes, this is a hack, but it's too late to repair this convoluted
        # control building process, so we do what we have to...
        self.control.sizeHint = _size_hint_wrapper(self.control.sizeHint, ui)