Beispiel #1
0
class ListDialog(Dialog):
    """
    Dialog to select an element from a list.
    It is implemented using the Tree widget.
    """
    def __init__(self, parent, title, provider, message=None, **kwargs):
        """ From kwargs:
                message: message tooltip to show when browsing.
                selected: the item that should be selected.
                validateSelectionCallback:
                    a callback function to validate selected items.
                allowSelect: if set to False, the 'Select' button will not
                    be shown.
                allowsEmptySelection: if set to True, it will not validate
                    that at least one element was selected.
        """
        self.values = []
        self.provider = provider
        self.message = message
        self.validateSelectionCallback = kwargs.get(
            'validateSelectionCallback', None)
        self._selectmode = kwargs.get('selectmode', 'extended')
        self._selectOnDoubleClick = kwargs.get('selectOnDoubleClick', False)
        self._allowsEmptySelection = kwargs.get('allowsEmptySelection', False)

        buttons = []
        if kwargs.get('allowSelect', True):
            buttons.append(('Select', RESULT_YES))
        buttons.append(('Cancel', RESULT_CANCEL))

        Dialog.__init__(self, parent, title, buttons=buttons, **kwargs)

    def body(self, bodyFrame):
        bodyFrame.config()
        gui.configureWeigths(bodyFrame)
        dialogFrame = tk.Frame(bodyFrame)
        dialogFrame.grid(row=0, column=0, sticky='news', padx=5, pady=5)
        dialogFrame.config()
        gui.configureWeigths(dialogFrame, row=1)
        self._createFilterBox(dialogFrame)
        self._createTree(dialogFrame)
        if self.message:
            label = tk.Label(bodyFrame,
                             text=self.message,
                             compound=tk.LEFT,
                             image=self.getImage(Icon.LIGHTBULB))
            label.grid(row=2, column=0, sticky='nw', padx=5, pady=5)
        self.initial_focus = self.tree

    def _createTree(self, parent):
        self.tree = BoundTree(parent,
                              self.provider,
                              selectmode=self._selectmode)
        if self._selectOnDoubleClick:
            self.tree.itemDoubleClick = lambda obj: self._handleResult(
                RESULT_YES)
        self.tree.grid(row=1, column=0)

    def _createFilterBox(self, content):
        """ Create the Frame with Filter widgets """
        def _onSearch(e=None):
            def comparison():
                pattern = self._searchVar.get().lower()
                return [
                    w[0] for w in self.lista.items()
                    if pattern in self.lista.get(w[0]).lower()
                ]

            self.tree.update()
            self.lista = {}

            for item in self.tree.get_children():

                itemStr = self.tree.item(item)['text']
                for value in self.tree.item(item)['values']:
                    itemStr = itemStr + " " + str(value)

                self.lista[item] = itemStr

            if self._searchVar.get() != '':
                matchs = comparison()
                if matchs:
                    for item in self.tree.get_children():
                        if item not in matchs:
                            self.tree.delete(item)
                else:
                    self.tree.delete(*self.tree.get_children())

        self.searchBoxframe = tk.Frame(content)
        label = tk.Label(self.searchBoxframe, text="Filter")
        label.grid(row=0, column=0, sticky='nw')
        self._searchVar = tk.StringVar(value='')
        self.entry = tk.Entry(self.searchBoxframe,
                              bg='white',
                              textvariable=self._searchVar,
                              width=40)

        self.entry.bind('<KeyRelease>', _onSearch)
        self.entry.focus_set()
        self.entry.grid(row=0, column=1, sticky='news')
        self.searchBoxframe.grid(row=0,
                                 column=0,
                                 sticky='news',
                                 padx=5,
                                 pady=(10, 5))

    def apply(self):
        self.values = self.tree.getSelectedObjects()

    def validate(self):
        self.apply()  # load self.values with selected items
        err = ''

        if self.values:
            if self.validateSelectionCallback:
                err = self.validateSelectionCallback(self.values)
        else:
            if not self._allowsEmptySelection:
                err = "Please select an element"

        if err:
            showError("Validation error", err, self)
            return False

        return True