<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def OnChar(self, event):
 """Key event method * Forces grid update on <Enter> key * Handles insertion of cell access code """


        if not self.ignore_changes:

            # Handle special keys
            keycode = event.GetKeyCode()

            if keycode == 13 and not self.GetStringSelection():
                # <Enter> pressed and no selection --> Focus on grid
                self.main_window.grid.SetFocus()

                # Ignore <Ctrl> + <Enter> and Quote content
                if event.ControlDown():
                    self.SetValue(quote(self.GetValue()))

                # Do not process <Enter>
                return

            elif keycode == 13 and self.GetStringSelection():
                # <Enter> pressed and selection
                # --> Place cursor at end of selection and clear selection
                selection_start, selection_stop = self.Selection
                self.SetSelection(selection_stop, selection_stop)

                # Do not process <Enter>
                return

            elif keycode == 9 and jedi is None:
                # Ignore the <Tab>
                return

            elif keycode == 9 and jedi is not None:
                #  If auto completion library jedi is present
                # <Tab> pressed --> show docstring tooltip

                tiptext = ""

                code = "".join(self.GetValue().split("\n"))
                position = self.GetInsertionPoint()

                # Get the docstring
                code_array = self.parent.parent.parent.grid.code_array
                env = code_array.get_globals()
                try:
                    script = jedi.Interpreter(code, [env], line=1,
                                              column=position)
                except ValueError:
                    # Jedi has thrown an error
                    event.Skip()
                    return

                completions = script.completions()
                completes = [completion.complete for completion in completions]
                complete = common_start(completes)

                if complete and \
                   not self.GetSelection()[1] > self.GetSelection()[0]:
                    # There is a non-empty completion
                    insertion_point = self.GetInsertionPoint()
                    self.write(complete)
                    if len(completes) > 1:
                        self.SetSelection(insertion_point,
                                          insertion_point + len(complete))

                words = [completion.name for completion in completions]

                docs = []
                for completion in completions:
                    doc = completion.docstring(fast=False)
                    if not doc and code:
                        # Is the completion part of a module?
                        code_segment = \
                            code[:position+1].split()[-1]
                        module_name = code_segment.rsplit(".", 1)[0]
                        try:
                            module = env[module_name]
                            doc = getattr(module, completion.name).__doc__
                        except (KeyError, AttributeError):
                            pass

                    if not doc:
                        name = completion.name
                        try:
                            # Is the completion a builtin?
                            doc = getattr(__builtin__, name).__doc__
                        except AttributeError:
                            pass
                    docs.append(doc)

                try:
                    dws = [": ".join([w, d]) for w, d in zip(words, docs)]

                    tiptext = "\n \n".join(dws)
                except TypeError:
                    pass

                # Cut tiptext length because Tooltip fails for long strings

                self.SetToolTip(wx.ToolTip(tiptext[:MAX_TOOLTIP_LENGTH]))

                # Do not process <Tab>
                return

        event.Skip()