def mouse_click(self, widget, event=None):
        """Implements shift- and control-key handling features for mouse button press events explicit

         The method is implements a fully defined mouse pattern to use shift- and control-key for multi-selection in a
         TreeView and a ListStore as model. It avoid problems caused by special renderer types like the text combo
         renderer by stopping the callback handler to continue with notifications.

        :param Gtk.Object widget: Object which is the source of the event
        :param Gtk.Event event: Event generated by mouse click
        :rtype: bool
        """

        if event.type == Gdk.EventType.BUTTON_PRESS:
            pthinfo = self.tree_view.get_path_at_pos(int(event.x), int(event.y))

            if not bool(event.get_state() & Gdk.ModifierType.CONTROL_MASK) \
                    and not bool(event.get_state() & Gdk.ModifierType.SHIFT_MASK) and \
                    event.type == Gdk.EventType.BUTTON_PRESS and event.get_button()[1] == 3:
                if pthinfo is not None:
                    model, paths = self._tree_selection.get_selected_rows()
                    # print(paths)
                    if pthinfo[0] not in paths:
                        # self._logger.info("force single selection for right click")
                        self.tree_view.set_cursor(pthinfo[0])
                        self._last_path_selection = pthinfo[0]
                    else:
                        # self._logger.info("single- or multi-selection for right click")
                        pass
                    self.on_right_click_menu()
                    return True

            if (bool(event.get_state() & Gdk.ModifierType.CONTROL_MASK) or \
                bool(event.get_state() & Gdk.ModifierType.SHIFT_MASK)) and \
                    event.type == Gdk.EventType.BUTTON_PRESS and event.get_button()[1] == 3:
                return True

            if not bool(event.get_state() & Gdk.ModifierType.SHIFT_MASK) and event.get_button()[1] == 1:
                if pthinfo is not None:
                    # self._logger.info("last select row {}".format(pthinfo[0]))
                    self._last_path_selection = pthinfo[0]
                # else:
                #     self._logger.info("deselect rows")
                #     self.tree_selection.unselect_all()

            if bool(event.get_state() & Gdk.ModifierType.SHIFT_MASK) and event.get_button()[1] == 1:
                # self._logger.info("SHIFT adjust selection range")
                model, paths = self._tree_selection.get_selected_rows()
                # print(model, paths, pthinfo[0])
                if paths and pthinfo and pthinfo[0]:
                    if self._last_path_selection[0] <= pthinfo[0][0]:
                        new_row_ids_selected = list(range(self._last_path_selection[0], pthinfo[0][0]+1))
                    else:
                        new_row_ids_selected = list(range(self._last_path_selection[0], pthinfo[0][0]-1, -1))
                    # self._logger.info("range to select {0}, {1}".format(new_row_ids_selected, model))
                    self._tree_selection.unselect_all()
                    for path in new_row_ids_selected:
                        self._tree_selection.select_path(path)
                    return True
                else:
                    # self._logger.info("nothing selected {}".format(model))
                    if pthinfo and pthinfo[0]:
                        self._last_path_selection = pthinfo[0]

            if bool(event.get_state() & Gdk.ModifierType.CONTROL_MASK) and event.get_button()[1] == 1:
                # self._logger.info("CONTROL adjust selection range")
                model, paths = self._tree_selection.get_selected_rows()
                # print(model, paths, pthinfo[0])
                if paths and pthinfo and pthinfo[0]:
                    if pthinfo[0] in paths:
                        self._tree_selection.unselect_path(pthinfo[0])
                    else:
                        self._tree_selection.select_path(pthinfo[0])
                    return True
                elif pthinfo and pthinfo[0]:
                    self._tree_selection.select_path(pthinfo[0])
                    return True

        elif event.type == Gdk.EventType._2BUTTON_PRESS:
            self._handle_double_click(event)
Implements shift- and control-key handling features for mouse button press events explicit

         The method is implements a fully defined mouse pattern to use shift- and control-key for multi-selection in a
         TreeView and a ListStore as model. It avoid problems caused by special renderer types like the text combo
         renderer by stopping the callback handler to continue with notifications.

        :param Gtk.Object widget: Object which is the source of the event
        :param Gtk.Event event: Event generated by mouse click
        :rtype: bool