def read_context(self, accessible): """ Extract prediction context from the accessible """ # get caret position from selection selection = None try: sel = accessible.get_selection(0) # Gtk-2 applications return 0,0 when there is no selection. # Gtk-3 applications return caret positions in that case. # LibreOffice Writer in Vivid initially returns -1,-1 when there # is no selection, later the caret position. start = sel.start_offset end = sel.end_offset if start > 0 and \ end > 0 and \ start <= end: selection = (sel.start_offset, sel.end_offset) except Exception as ex: # Private exception gi._glib.GErro _logger.info("DomainGenericText.read_context(), selection: " \ + unicode_str(ex)) # get text around the caret position try: if selection is None: offset = accessible.get_caret_offset() selection = (offset, offset) r = accessible.get_text_at_offset( selection[0], Atspi.TextBoundaryType.LINE_START) count = accessible.get_character_count() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text: " \ + unicode_str(ex)) return None line = unicode_str(r.content).replace("\n", "") line_caret = max(selection[0] - r.start_offset, 0) begin = max(selection[0] - 256, 0) end = min(selection[0] + 100, count) try: text = Atspi.Text.get_text(accessible, begin, end) except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text2: " \ + unicode_str(ex)) return None text = unicode_str(text) # Not all text may be available for large selections. We only need the # part before the begin of the selection/caret. selection_span = TextSpan(selection[0], selection[1] - selection[0], text, begin) context = text[:selection[0] - begin] begin_of_text = begin == 0 begin_of_text_offset = 0 return (context, line, line_caret, selection_span, begin_of_text, begin_of_text_offset)
def read_context(self, accessible, offset=None): """ Extract prediction context from the accessible """ if offset is None: try: offset = accessible.get_caret_offset() except Exception as ex: # Private exception gi._glib.GError # when gedit became unresponsive. _logger.info("DomainTerminal.read_context(): " + unicode_str(ex)) return None context_lines, prompt_length, line, line_start, line_caret = \ self._get_text_after_prompt(accessible, offset) if prompt_length: begin_of_text = True begin_of_text_offset = line_start else: begin_of_text = False begin_of_text_offset = None context = "".join(context_lines) before_line = "".join(context_lines[:-1]) selection_span = TextSpan(offset, 0, before_line + line, line_start - len(before_line)) result = (context, line, line_caret, selection_span, begin_of_text, begin_of_text_offset) return result
def read_context(self, accessible, offset=None): """ Extract prediction context from the accessible """ if offset is None: try: offset = accessible.get_caret_offset() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainTerminal.read_context(): " \ + unicode_str(ex)) return None # remove prompt from the current or previous lines context, context_start, line, line_start, line_cursor = \ self._read_after_prompt(accessible, offset) if context_start: begin_of_text = True begin_of_text_offset = line_start else: begin_of_text = False begin_of_text_offset = None # remove newlines context = context.replace("\n", "") #cursor_span = TextSpan(offset, 0, text, begin) cursor_span = TextSpan(offset, 0, line, line_start) result = (context, line, line_cursor, cursor_span, begin_of_text, begin_of_text_offset) return result
def read_context(self, accessible): """ Extract prediction context from the accessible """ try: offset = accessible.get_caret_offset() r = accessible.get_text_at_offset( offset, Atspi.TextBoundaryType.LINE_START) count = accessible.get_character_count() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(): " \ + unicode_str(ex)) return None line = unicode_str(r.content).replace("\n", "") line_cursor = max(offset - r.start_offset, 0) begin = max(offset - 256, 0) end = min(offset + 100, count) text = Atspi.Text.get_text(accessible, begin, end) text = unicode_str(text) cursor_span = TextSpan(offset, 0, text, begin) context = text[:offset - begin] begin_of_text = begin == 0 begin_of_text_offset = 0 return (context, line, line_cursor, cursor_span, begin_of_text, begin_of_text_offset)
def __init__(self, wp): self._wp = wp self._accessible = None self._can_insert_text = False self._text_domains = TextDomains() self._text_domain = self._text_domains.get_nop_domain() self._changes = TextChanges() self._entering_text = False self._text_changed = False self._context = "" self._line = "" self._line_caret = 0 self._selection_span = TextSpan() self._begin_of_text = False # context starts at begin of text? self._begin_of_text_offset = None # offset of text begin self._pending_separator_span = None self._last_text_change_time = 0 self._last_caret_move_time = 0 self._last_caret_move_position = 0 self._last_context = None self._last_line = None self._update_context_timer = Timer() self._update_context_delay_normal = 0.01 self._update_context_delay = self._update_context_delay_normal
def read_context(self, keyboard, accessible): """ Extract prediction context from the accessible """ # get caret position from selection selection = accessible.get_selection() # get text around the caret position try: count = accessible.get_character_count() if selection is None: offset = accessible.get_caret_offset() # In Zesty, firefox 50.1 often returns caret position -1 # when typing into the urlbar. Assume we are at the end # of the text when that happens. if offset < 0: _logger.warning("DomainGenericText.read_context(): " "Atspi.Text.get_caret_offset() " "returned invalid {}. " "Pretending the cursor is at the end " "of the text at offset {}." .format(offset, count)) offset = count selection = (offset, offset) r = accessible.get_text_at_offset( selection[0], Atspi.TextBoundaryType.LINE_START) except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text: " + unicode_str(ex)) return None line = unicode_str(r.content).replace("\n", "") line_caret = max(selection[0] - r.start_offset, 0) begin = max(selection[0] - 256, 0) end = min(selection[0] + 100, count) try: text = accessible.get_text(begin, end) except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text2: " + unicode_str(ex)) return None text = unicode_str(text) # Not all text may be available for large selections. We only need the # part before the begin of the selection/caret. selection_span = TextSpan(selection[0], selection[1] - selection[0], text, begin) context = text[:selection[0] - begin] begin_of_text = begin == 0 begin_of_text_offset = 0 return (context, line, line_caret, selection_span, begin_of_text, begin_of_text_offset)
def _record_text_change(self, pos, length, insert): accessible = self._accessible insertion_span = None char_count = None if accessible: try: char_count = accessible.get_character_count() except: # gi._glib.GError: The application no longer exists # when closing a tab in gnome-terminal. char_count = None if char_count is not None: # record the change spans_to_update = [] if insert: if self._entering_text and \ self.can_record_insertion(accessible, pos, length): if self._wp.is_typing() or length < 30: # Remember all of the insertion, might have been # a pressed snippet or wordlist button. include_length = -1 else: # Remember only the first few characters. # Large inserts can be paste, reload or scroll # operations. Only learn the first word of these. include_length = 2 # simple span for current insertion begin = max(pos - 100, 0) end = min(pos + length + 100, char_count) text = self._state_tracker.get_accessible_text(accessible, begin, end) if text is not None: insertion_span = TextSpan(pos, length, text, begin) else: # Remember nothing, just update existing spans. include_length = None spans_to_update = self._changes.insert(pos, length, include_length) else: spans_to_update = self._changes.delete(pos, length, self._entering_text) # update text of all modified spans for span in spans_to_update: # Get some more text around the span to hopefully # include whole words at beginning and end. begin = max(span.begin() - 100, 0) end = min(span.end() + 100, char_count) span.text = Atspi.Text.get_text(accessible, begin, end) span.text_pos = begin self._text_changed = True return insertion_span
def __init__(self, wp): self._wp = wp self._accessible = None self._can_insert_text = False self._text_domains = TextDomains() self._text_domain = self._text_domains.get_nop_domain() self._changes = TextChanges() self._entering_text = False self._text_changed = False self._context = "" self._line = "" self._line_cursor = 0 self._span_at_cursor = TextSpan() self._begin_of_text = False # context starts at begin of text? self._begin_of_text_offset = None # offset of text begin self._last_context = None self._last_line = None self._update_context_timer = Timer()
def read_context(self, accessible): return "", "", 0, TextSpan(), False, 0