Example #1
0
class SimpleEditor ( EditorWithList, IValueChangeListener ):
    """ Simple style of editor for checklists, which displays a combo box.
    """

    #---------------------------------------------------------------------------
    #  Trait definitions:
    #---------------------------------------------------------------------------

    # Checklist item names
    names = List( Unicode )

    # Checklist item values
    values = List

    #---------------------------------------------------------------------------
    #  Finishes initializing the editor by creating the underlying toolkit
    #  widget:
    #---------------------------------------------------------------------------

    def init ( self, parent ):
        """ Finishes initializing the editor by creating the underlying toolkit
            widget.
        """
        self.create_control( parent )
        super( SimpleEditor, self ).init( parent )
        self.set_tooltip()

    #---------------------------------------------------------------------------
    #  Creates the initial editor control:
    #---------------------------------------------------------------------------

    def create_control ( self, parent ):
        """ Creates the initial editor control.
        """
        self.control = ComboBox()
        self.control.setMultiSelect(False)
        self.control.setNullSelectionAllowed(True)
        self.control.setImmediate(True)
        self.control.addListener(self, IValueChangeListener)

    #---------------------------------------------------------------------------
    #  Handles the list of legal check list values being updated:
    #---------------------------------------------------------------------------

    def list_updated ( self, values ):
        """ Handles updates to the list of legal checklist values.
        """
        sv = self.string_value
        if (len( values ) > 0) and isinstance( values[0], basestring ):
            values = [ ( x, sv( x, capitalize ) ) for x in values ]
        self.values = valid_values = [ x[0] for x in values ]
        self.names  =                [ x[1] for x in values ]

        # Make sure the current value is still legal:
        modified  = False
        cur_value = parse_value( self.value )
        for i in range( len( cur_value ) - 1, -1, -1 ):
            if cur_value[i] not in valid_values:
                try:
                    del cur_value[i]
                    modified = True
                except TypeError:
                    logger.warn('Unable to remove non-current value [%s] from '
                        'values %s', cur_value[i], values)
        if modified:
            if isinstance( self.value, basestring ):
                cur_value = ','.join( cur_value )
            self.value = cur_value

        self.rebuild_editor()

    #---------------------------------------------------------------------------
    #  Rebuilds the editor after its definition is modified:
    #---------------------------------------------------------------------------

    def rebuild_editor ( self ):
        """ Rebuilds the editor after its definition is modified.
        """
        control = self.control
        c = IndexedContainer()
        for name in self.names:
            c.addItem(name)
        control.setContainerDataSource(c)
        self.update_editor()

    #---------------------------------------------------------------------------
    #  Handles the user selecting a new value from the combo box:
    #---------------------------------------------------------------------------

    def valueChange(self, event):
        v = str(event.getProperty())
        self.update_object(v)

    def update_object ( self, text ):
        """ Handles the user selecting a new value from the combo box.
        """
        if unicode(text) in self.names:
            value = self.values[self.names.index(unicode(text))]
            if not isinstance(self.value, basestring):
                value = [value]
        elif not isinstance(self.value, basestring):
            value = []
        else:
            value = ''
        self.value = value

    #---------------------------------------------------------------------------
    #  Updates the editor when the object trait changes external to the editor:
    #---------------------------------------------------------------------------

    def update_editor ( self ):
        """ Updates the editor when the object trait changes externally to the
            editor.
        """
        try:
            self.control.select( parse_value(self.value)[0] )
        except:
            pass
Example #2
0
class MuntjacComboBox(MuntjacControl, AbstractTkComboBox):
    """ A Muntjac implementation of ComboBox.

    Use a combo box to select a single item from a collection of items.

    """
    #--------------------------------------------------------------------------
    # Setup methods
    #--------------------------------------------------------------------------
    def create(self, parent):
        """ Creates a QComboBox.

        """
        self.widget = ComboBox()
        self.widget.setImmediate(True)
        parent.addComponent(self.widget)

    def initialize(self):
        """ Intializes the widget with the attributes of this instance.

        """
        super(MuntjacComboBox, self).initialize()
        shell = self.shell_obj
        self.set_items(shell.labels)
        self.set_selection(shell.index)

    def bind(self):
        """ Connects the event handlers for the combo box.

        """
        super(MuntjacComboBox, self).bind()
        self.widget.currentIndexChanged.connect(self.on_selected)

    #--------------------------------------------------------------------------
    # Implementation
    #--------------------------------------------------------------------------
    def shell_index_changed(self, index):
        """ The change handler for the 'index' attribute on the shell
        object.

        """
        self.set_selection(index)

    def shell_labels_changed(self, labels):
        """ The change handler for the 'labels' attribute on the shell
        object.

        """
        self.set_items(labels)

    def on_selected(self):
        """ The event handler for a combo box selection event.

        """
        if not guard.guarded(self, 'updating'):
            shell = self.shell_obj
            curr_index = self._selected_index()
            shell.index = curr_index

            # Only fire the selected event if we have a valid selection
            if curr_index != -1:
                shell.selected = shell.value

    def set_items(self, str_items):
        """ Sets the items in the combo box.

        """
        # We need to avoid a feedback loop when updating the items in
        # the combo box. Qt will emit index changed signals when the
        # items are updated. But, the shell object has already computed
        # the proper index for the new items, so we use that to update
        # the index of the control after updating the items. The flag
        # is read by the on_selected handler to ignore updates during
        # this process.
        with guard(self, 'updating'):
            widget = self.widget
            widget.removeAllItems()
            for item in str_items:
                widget.addItem(item)
            ids = widget.getItemIds()
            widget.select(ids[self.shell_obj.index])

    def set_selection(self, index):
        """ Sets the value in the combo box, or resets the combo box
        if the value is not in the list of items.

        """
        # We need to avoid a feedback loop when updating the selection
        # in the combo box. Qt will emit index changed signals when the
        # selectino is updated. But, the shell object has already computed
        # the proper index for the new selection so we don't need to feed
        # back while doing this.
        with guard(self, 'updating'):
            ids = self.widget.getItemIds()
            self.widget.select(ids[index])

    #--------------------------------------------------------------------------
    # Helper Methods
    #--------------------------------------------------------------------------
    def _selected_index(self):
        widget = self.widget
        ids = widget.getItemIds()
        val = widget.getValue()
        if val in ids:
            curr_index = ids.index(val)
        else:
            curr_index = -1
        return curr_index