def test_escape_unescape_translation(self): for raw, escaped in ( # No change. ('foobar', 'foobar'), (r'\\', r'\\'), ('\\\\\\', '\\\\\\'), # -> \\\ # Basic support: \n, \r, \t. ('\n', r'\n'), ('\r', r'\r'), ('\t', r'\t'), # Allow a literal \n, \r, or \t by doubling the \. (r'\n', r'\\n'), (r'\r', r'\\r'), (r'\t', r'\\t'), (r'\\n', r'\\\n'), (r'\\r', r'\\\r'), (r'\\t', r'\\\t'), # A little more complex. ('\tfoo\nbar\r', r'\tfoo\nbar\r'), ('\\tfoo\\nbar\\r', r'\\tfoo\\nbar\\r'), ): result = unescape_translation(escaped) self.assertEqual(result, raw, msg='unescape_translation(%r)=%r != %r' % (escaped, result, raw)) result = escape_translation(raw) self.assertEqual(result, escaped, msg='escape_translation(%r)=%r != %r' % (raw, result, escaped))
def prepend(self, suggestion_list): before_height = self.suggestions.document().size().height() cursor = self.suggestions.textCursor() cursor.movePosition(QTextCursor.Start) for suggestion in suggestion_list: cursor.insertBlock() cursor.setCharFormat(self._translation_char_format) cursor.block().setUserState(self.STYLE_TRANSLATION) cursor.insertText(escape_translation(suggestion.text) + u':') if not suggestion.steno_list: cursor.insertText(u' ' + _('no suggestions')) continue for strokes_list in suggestion.steno_list[:10]: cursor.insertBlock() cursor.setCharFormat(self._strokes_char_format) cursor.block().setUserState(self.STYLE_STROKES) cursor.insertText(u' ' + u'/'.join(strokes_list)) cursor.insertText('\n') # Keep current position when not at the top of the document. scrollbar_value = self.suggestions.verticalScrollBar().value() if scrollbar_value != 0: after_height = self.suggestions.document().size().height() delta_height = after_height - before_height self.suggestions.verticalScrollBar().setValue(scrollbar_value + delta_height)
def __init__(self, engine, config): self.config = config self.engine = engine self.all_keys = [] self.filtered_keys = [] self.sorted_keys = [] self.modified_items = [] self.added_items = [] self.deleted_items = [] self.sorting_column = -1 self.sorting_mode = None item_id = 0 self.new_id = -1 self.pending_changes = False for dictionary in reversed(self.engine.get_dictionary().dicts): for dk, translation in dictionary.iteritems(): joined = '/'.join(dk) item = DictionaryItem(joined, escape_translation(translation), dictionary, item_id) self.all_keys.append(item) item_id += 1 self.filtered_keys = self.all_keys[:] self.sorted_keys = self.filtered_keys[:]
def format_label(fmt, strokes, translation): if strokes: strokes = ", ".join("/".join(s) for s in sort_steno_strokes(strokes)) if translation: translation = escape_translation(translation) return fmt.format(strokes=strokes, translation=translation)
def _format_label(self, fmt, strokes, translation): if strokes: strokes = ', '.join(self._special_fmt % html_escape('/'.join(s)) for s in sort_steno_strokes(strokes)) if translation: translation = self._special_fmt % html_escape(escape_translation(translation)) return fmt.format(strokes=strokes, translation=translation)
def _format_label(self, fmt, strokes, translation=None, filename=None): if strokes: strokes = ', '.join(self._special_fmt % html_escape('/'.join(s)) for s in sort_steno_strokes(strokes)) if translation: translation = self._special_fmt_bold % html_escape(escape_translation(translation)) if filename: filename = html_escape(filename) return fmt.format(strokes=strokes, translation=translation, filename=filename)
def data(self, index, role): if not index.isValid() or role not in (Qt.EditRole, Qt.DisplayRole): return None item = self._entries[index.row()] column = index.column() if column == _COL_STENO: return '/'.join(item.strokes) if column == _COL_TRANS: return escape_translation(item.translation) if column == _COL_DICT: return shorten_path(item.dictionary.get_path())
def show_suggestions(self, suggestion_list): # Limit history. undo_levels = self.config.get_undo_levels() while len(self.history) >= undo_levels: _, text_length = self.history.pop(0) last_position = self.listbox.GetLastPosition() self.listbox.Remove(last_position - text_length, last_position) # Insert last entry on top. self.listbox.SetInsertionPoint(0) # Find available text width. max_width = self.listbox.Size[0] # Yes, 2 times the scrollbar width, because... max_width -= 2 * wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X) dc = wx.ScreenDC() dc.SetFont(self.stroke_style.GetFont()) for suggestion in suggestion_list: self.listbox.SetDefaultStyle(self.word_style) self.listbox.WriteText( shorten_unicode(escape_translation(suggestion.text)) + u'\n' ) if not suggestion.steno_list: self.listbox.SetDefaultStyle(self.no_suggestion_style) self.listbox.WriteText(self.no_suggestion_indent) self.listbox.WriteText(u'No suggestions\n') continue self.listbox.SetDefaultStyle(self.stroke_style) # Limit arbitrarily to 10 suggestions per word. for stroke_list in suggestion.steno_list[:10]: line_text = None for n, stroke in enumerate(stroke_list): if 0 == n: line_text = text = self.strokes_indent + stroke else: text = u'/' + stroke line_text += text if dc.GetTextExtent(line_text)[0] >= max_width: line_text = 2 * self.strokes_indent + text text = u'\n' + line_text self.listbox.WriteText(shorten_unicode(text)) self.listbox.WriteText(u'\n') length = self.listbox.GetInsertionPoint() assert length self.history.append((suggestion_list, length)) # Reset style after final \n, so following # word is correctly displayed. self.listbox.SetDefaultStyle(self.word_style) self.listbox.WriteText('') # Make sure first line is shown. self.listbox.ShowPosition(0)
def show_suggestions(self, suggestion_list): # Limit history. undo_levels = self.config.get_undo_levels() while len(self.history) >= undo_levels: _, text_length = self.history.pop(0) last_position = self.listbox.GetLastPosition() self.listbox.Remove(last_position - text_length, last_position) # Insert last entry on top. self.listbox.SetInsertionPoint(0) # Find available text width. max_width = self.listbox.Size[0] # Yes, 2 times the scrollbar width, because... max_width -= 2 * wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X) dc = wx.ScreenDC() dc.SetFont(self.stroke_style.GetFont()) for suggestion in suggestion_list: self.listbox.SetDefaultStyle(self.word_style) self.listbox.WriteText( shorten_unicode(escape_translation(suggestion.text)) + u'\n') if not suggestion.steno_list: self.listbox.SetDefaultStyle(self.no_suggestion_style) self.listbox.WriteText(self.no_suggestion_indent) self.listbox.WriteText(u'No suggestions\n') continue self.listbox.SetDefaultStyle(self.stroke_style) # Limit arbitrarily to 10 suggestions per word. for stroke_list in suggestion.steno_list[:10]: line_text = None for n, stroke in enumerate(stroke_list): if 0 == n: line_text = text = self.strokes_indent + stroke else: text = u'/' + stroke line_text += text if dc.GetTextExtent(line_text)[0] >= max_width: line_text = 2 * self.strokes_indent + text text = u'\n' + line_text self.listbox.WriteText(shorten_unicode(text)) self.listbox.WriteText(u'\n') length = self.listbox.GetInsertionPoint() assert length self.history.append((suggestion_list, length)) # Reset style after final \n, so following # word is correctly displayed. self.listbox.SetDefaultStyle(self.word_style) self.listbox.WriteText('') # Make sure first line is shown. self.listbox.ShowPosition(0)
def _format_suggestion(self, index): suggestion = index.data(Qt.DisplayRole) self._doc.clear() cursor = QTextCursor(self._doc) cursor.setCharFormat(self._translation_char_format) cursor.insertText(escape_translation(suggestion.text) + ':') if not suggestion.steno_list: cursor.insertText(' ' + NO_SUGGESTIONS_STRING) return for strokes_list in suggestion.steno_list[:MAX_SUGGESTIONS_COUNT]: cursor.insertBlock() cursor.setCharFormat(self._strokes_char_format) cursor.insertText(' ' + '/'.join(strokes_list))
def on_strokes_edited(self): strokes = self._strokes() if strokes: translation = self._engine.raw_lookup(strokes) strokes = '/'.join(strokes) if translation is not None: fmt = _('{strokes} maps to "{translation}"') translation = escape_translation(translation) else: fmt = _('{strokes} is not in the dictionary') info = fmt.format(strokes=strokes, translation=translation) else: info = '' self.strokes_info.setText(info)
def on_translation_edited(self): translation = self._translation() if translation: strokes = self._engine.reverse_lookup(translation) translation = escape_translation(translation) if strokes: fmt = _('"{translation}" is mapped from {strokes}') strokes = ', '.join('/'.join(x) for x in strokes) else: fmt = _('"{translation}" is not in the dictionary') info = fmt.format(strokes=strokes, translation=translation) else: info = '' self.translation_info.setText(info)
def on_strokes_change(self, event): key = self._normalized_strokes() if key: d = self.engine.get_dictionary() translation = d.raw_lookup(key) strokes = '/'.join(key) if translation: label = '%s maps to %s' % (strokes, escape_translation(translation)) else: label = '%s is not in the dictionary' % strokes label = util.shorten_unicode(label) else: label = '' self.stroke_mapping_text.SetLabel(label) self.GetSizer().Layout()
def data(self, index, role): if not index.isValid(): return None suggestion = self._suggestion_list[index.row()] if role == Qt.DisplayRole: return suggestion if role == Qt.AccessibleTextRole: translation = escape_translation(suggestion.text) if suggestion.steno_list: steno = ', '.join( '/'.join(strokes_list) for strokes_list in suggestion.steno_list[:MAX_SUGGESTIONS_COUNT]) else: steno = NO_SUGGESTIONS_STRING return translation + ': ' + steno return None
def on_translation_change(self, event): translation = event.GetString() self.listbox.Clear() if translation: suggestions = self.engine.get_suggestions( unescape_translation(translation) ) if suggestions: for suggestion, strokes in suggestions: self.listbox.Append(escape_translation(suggestion)) entries = ('/'.join(x) for x in strokes) for entry in entries: self.listbox.Append(' %s' % (entry)) self.listbox.EnsureVisible(0) else: self.listbox.Append('No entries') self.GetSizer().Layout()
def _on_translated(self, _old, new): if len(new) == 0: # true if the stroke is an undo stroke return with self.engine: last_translations = self.engine.translator_state.translations retro_formatter = RetroFormatter(last_translations) split_words = retro_formatter.last_words(10, rx=self.WORD_RX) # last few "phrases", e.g. "let's go", "'s go", "s go", "go" phrases = set( ("".join(split_words[i:]) for i in range(len(split_words)))) # last translation in case it isn't shown exactly, e.g. "{#Return}{^}", {^ing} if len(last_translations) > 0: last_translation = last_translations[-1].english if last_translation is not None: phrases.add(escape_translation(last_translation)) for phrase in phrases: for suggestion in self.engine.get_suggestions(phrase): self.card_suggestions.add_suggestion(suggestion)
def append(self, suggestion_list): scrollbar = self.suggestions.verticalScrollBar() scroll_at_end = scrollbar.value() == scrollbar.maximum() cursor = self.suggestions.textCursor() cursor.movePosition(QTextCursor.End) for suggestion in suggestion_list: cursor.insertBlock() cursor.setCharFormat(self._translation_char_format) cursor.block().setUserState(self.STYLE_TRANSLATION) cursor.insertText(escape_translation(suggestion.text) + u':') if not suggestion.steno_list: cursor.insertText(u' ' + _('no suggestions')) continue for strokes_list in suggestion.steno_list[:10]: cursor.insertBlock() cursor.setCharFormat(self._strokes_char_format) cursor.block().setUserState(self.STYLE_STROKES) cursor.insertText(u' ' + u'/'.join(strokes_list)) cursor.insertText('\n') # Keep current position when not at the end of the document. if scroll_at_end: scrollbar.setValue(scrollbar.maximum())
def append(self, suggestion_list, keep_position=False): scrollbar = self.suggestions.verticalScrollBar() scroll_at_end = scrollbar.value() == scrollbar.maximum() cursor = self.suggestions.textCursor() cursor.movePosition(QTextCursor.End) for suggestion in suggestion_list: cursor.insertBlock() cursor.setCharFormat(self._translation_char_format) cursor.block().setUserState(self.STYLE_TRANSLATION) cursor.insertText(escape_translation(suggestion.text) + ':') if not suggestion.steno_list: cursor.insertText(' ' + _('no suggestions')) continue for strokes in suggestion.steno_list[:10]: cursor.insertBlock() cursor.setCharFormat(self._strokes_char_format) cursor.block().setUserState(self.STYLE_STROKES) cursor.insertText(' ' + strokes) cursor.insertText('\n') # Keep current position when not at the end of the document, or if the argument says so # Otherwise, scroll the window down to keep the new suggestions in view if scroll_at_end and not keep_position: scrollbar.setValue(scrollbar.maximum())
def test_escape_unescape_translation(raw, escaped): assert unescape_translation(escaped) == raw assert escape_translation(raw) == escaped