1

Some basic support for displaying information about characters

Former-commit-id: 895554df1f912021309091c88cd5b3c2a8b7211f
This commit is contained in:
Alex Yatskov 2013-11-10 20:27:25 -08:00
parent bd5fe72ab2
commit d279b2bf28
5 changed files with 104 additions and 36 deletions

View File

@ -5,6 +5,7 @@
"fontFamily": "Arial", "fontFamily": "Arial",
"fontSize": 12, "fontSize": 12,
"loadRecentFile": true, "loadRecentFile": true,
"maxResults": 20,
"profiles": {}, "profiles": {},
"recentFiles": [], "recentFiles": [],
"scanLength": 16, "scanLength": 16,

View File

@ -46,6 +46,8 @@ class Dictionary:
def findCharacter(self, character): def findCharacter(self, character):
self.requireIndex('Kanji', 'character')
cursor = self.db.cursor() cursor = self.db.cursor()
cursor.execute('SELECT * FROM Kanji WHERE character=? LIMIT 1', character) cursor.execute('SELECT * FROM Kanji WHERE character=? LIMIT 1', character)
@ -66,12 +68,18 @@ class Dictionary:
for radical in self.findRadicalsByCharacter(character): for radical in self.findRadicalsByCharacter(character):
radicals[radical] = radicals.get(radical, 0) + 1 radicals[radical] = radicals.get(radical, 0) + 1
results = dict() characters = dict()
for radical, count in radicals.items(): for radical, count in radicals.items():
for character in self.findCharactersByRadical(radical): for character in self.findCharactersByRadical(radical):
results[character] = results.get(character, 0) + count characters[character] = characters.get(character, 0) + count
return sorted(results.items(), key=operator.itemgetter(1), reverse=True) results = list()
for character, score in sorted(characters.items(), key=operator.itemgetter(1), reverse=True):
result = self.findCharacter(character)
if result is not None:
results.append(result)
return results
def findRadicalsByCharacter(self, character): def findRadicalsByCharacter(self, character):

View File

@ -26,11 +26,11 @@ class Translator:
self.dictionary = dictionary self.dictionary = dictionary
def findTerm(self, selection, partial=False): def findTerm(self, text, partial=False):
groups = dict() groups = dict()
for i in xrange(len(selection), 0, -1): for i in xrange(len(text), 0, -1):
term = selection[:i] term = text[:i]
deinflections = self.deinflector.deinflect(term, self.validator) deinflections = self.deinflector.deinflect(term, self.validator)
if deinflections is None: if deinflections is None:
@ -50,6 +50,14 @@ class Translator:
return results, length return results, length
def findCharacter(self, text):
return self.dictionary.findCharacter(text)
def findCharacterVisually(self, text):
return self.dictionary.findCharacterVisually(text)
def processTerm(self, groups, source, rules=list(), root=str(), partial=False): def processTerm(self, groups, source, rules=list(), root=str(), partial=False):
root = root or source root = root or source

View File

@ -58,7 +58,8 @@ class MainWindowReader(QtGui.QMainWindow, gen.reader_ui.Ui_MainWindowReader):
self.applyPreferences() self.applyPreferences()
self.updateRecentFiles() self.updateRecentFiles()
self.updateDefinitions() self.updateVocabDefs()
self.updateKanjiDefs()
if filename: if filename:
self.openFile(filename) self.openFile(filename)
@ -264,17 +265,23 @@ class MainWindowReader(QtGui.QMainWindow, gen.reader_ui.Ui_MainWindowReader):
def onVocabDefSearchReturn(self): def onVocabDefSearchReturn(self):
text = unicode(self.textVocabSearch.text()) text = unicode(self.textVocabSearch.text())
self.state.vocabDefs, length = self.language.findTerm(text, True) self.state.vocabDefs, length = self.language.findTerm(text, True)
self.updateDefinitions() self.updateVocabDefs()
def onKanjiDefSearchReturn(self): def onKanjiDefSearchReturn(self):
text = unicode(self.textKanjiSearch.text()) text = unicode(self.textKanjiSearch.text())
self.updateDefinitions() if len(text) == 1:
result = self.language.findCharacter(text)
self.state.kanjiDefs = list() if result is None else [result]
else:
self.state.kanjiDefs = self.language.findCharacterVisually(text)
self.updateKanjiDefs()
def onDefinitionDoubleClicked(self, item): def onDefinitionDoubleClicked(self, item):
if self.anki is not None: if self.anki is not None:
row = self.listDefinitions.row(item) row = self.istDefinitions.row(item)
self.anki.browseNote(self.addedFacts[row]) self.anki.browseNote(self.addedFacts[row])
@ -429,7 +436,7 @@ class MainWindowReader(QtGui.QMainWindow, gen.reader_ui.Ui_MainWindowReader):
if self.anki is None: if self.anki is None:
return False return False
profile = self.preferences["profiles"].get(profile) profile = self.preferences['profiles'].get(profile)
if profile is None: if profile is None:
return False return False
@ -458,7 +465,8 @@ class MainWindowReader(QtGui.QMainWindow, gen.reader_ui.Ui_MainWindowReader):
self.listDefinitions.setCurrentRow(self.listDefinitions.count() - 1) self.listDefinitions.setCurrentRow(self.listDefinitions.count() - 1)
self.setStatus(u'Added expression {0}; {1} new fact(s) total'.format(markup['expression'], len(self.addedFacts))) self.setStatus(u'Added expression {0}; {1} new fact(s) total'.format(markup['expression'], len(self.addedFacts)))
self.updateDefinitions() self.updateVocabDefs()
self.updateKanjiDefs()
return True return True
@ -466,7 +474,7 @@ class MainWindowReader(QtGui.QMainWindow, gen.reader_ui.Ui_MainWindowReader):
if self.anki is None: if self.anki is None:
return False return False
profile = self.preferences["profiles"].get(profile) profile = self.preferences['profiles'].get(profile)
if profile is None: if profile is None:
return False return False
@ -503,7 +511,7 @@ class MainWindowReader(QtGui.QMainWindow, gen.reader_ui.Ui_MainWindowReader):
for definition in self.state.vocabDefs: for definition in self.state.vocabDefs:
definition['sentence'] = sentence definition['sentence'] = sentence
self.updateDefinitions() self.updateVocabDefs()
lengthSelect = 0 lengthSelect = 0
if lengthMatched: if lengthMatched:
@ -566,10 +574,21 @@ class MainWindowReader(QtGui.QMainWindow, gen.reader_ui.Ui_MainWindowReader):
self.preferences.updateRecentFile(self.state.filename, self.state.scanPosition) self.preferences.updateRecentFile(self.state.filename, self.state.scanPosition)
def updateDefinitions(self): def updateVocabDefs(self):
html = reader_util.buildVocabDefs(self.state.vocabDefs, self.ankiIsFactValid) html = reader_util.buildVocabDefs(
self.state.vocabDefs[:self.preferences['maxResults']],
self.ankiIsFactValid
)
self.textVocabDefs.setHtml(html) self.textVocabDefs.setHtml(html)
def updateKanjiDefs(self):
html = reader_util.buildKanjiDefs(
self.state.kanjiDefs[:self.preferences['maxRsults']],
self.ankiIsFactValid
)
self.textKanjiDefs.setHtml(html)
def setStatus(self, status): def setStatus(self, status):
self.statusBar.showMessage(status) self.statusBar.showMessage(status)

View File

@ -122,7 +122,23 @@ def copyVocabDefs(definitions):
QtGui.QApplication.clipboard().setText(text) QtGui.QApplication.clipboard().setText(text)
def buildVocabDef(definition, factIndex, factQuery): def buildDefHeader():
palette = QtGui.QApplication.palette()
toolTipBg = palette.color(QtGui.QPalette.Window).name()
toolTipFg = palette.color(QtGui.QPalette.WindowText).name()
return u"""
<html><head><style>
body {{ background-color: {0}; color: {1}; font-size: 11pt; }}
span.expression {{ font-size: 15pt; }}
</style></head><body>""".format(toolTipBg, toolTipFg)
def buildDefFooter():
return '</body></html>'
def buildVocabDef(definition, index, query):
reading = unicode() reading = unicode()
if definition['reading']: if definition['reading']:
reading = u'[{0}]'.format(definition['reading']) reading = u'[{0}]'.format(definition['reading'])
@ -132,12 +148,12 @@ def buildVocabDef(definition, factIndex, factQuery):
rules = ' &bull; '.join(definition['rules']) rules = ' &bull; '.join(definition['rules'])
rules = '<span class = "rules">&lt;{0}&gt;<br/></span>'.format(rules) rules = '<span class = "rules">&lt;{0}&gt;<br/></span>'.format(rules)
links = '<a href = "copyVocabDef:{0}"><img src = "://img/img/icon_copy_definition.png" align = "right"/></a>'.format(factIndex) links = '<a href = "copyVocabDef:{0}"><img src = "://img/img/icon_copy_definition.png" align = "right"/></a>'.format(index)
if factQuery: if query:
if factQuery('vocab', markupVocabExp(definition)): if query('vocab', markupVocabExp(definition)):
links += '<a href = "addVocabExp:{0}"><img src = "://img/img/icon_add_expression.png" align = "right"/></a>'.format(factIndex) links += '<a href = "addVocabExp:{0}"><img src = "://img/img/icon_add_expression.png" align = "right"/></a>'.format(index)
if factQuery('vocab', markupVocabReading(definition)): if query('vocab', markupVocabReading(definition)):
links += '<a href = "addVocabReading:{0}"><img src = "://img/img/icon_add_reading.png" align = "right"/></a>'.format(factIndex) links += '<a href = "addVocabReading:{0}"><img src = "://img/img/icon_add_reading.png" align = "right"/></a>'.format(index)
html = u""" html = u"""
<span class = "links">{0}</span> <span class = "links">{0}</span>
@ -149,25 +165,41 @@ def buildVocabDef(definition, factIndex, factQuery):
return html return html
def buildVocabDefs(definitions, factQuery): def buildVocabDefs(definitions, query):
palette = QtGui.QApplication.palette() html = buildDefHeader()
toolTipBg = palette.color(QtGui.QPalette.Window).name()
toolTipFg = palette.color(QtGui.QPalette.WindowText).name()
html = u"""
<html><head><style>
body {{ background-color: {0}; color: {1}; font-size: 11pt; }}
span.expression {{ font-size: 15pt; }}
</style></head><body>""".format(toolTipBg, toolTipFg)
if len(definitions) > 0: if len(definitions) > 0:
for i, definition in enumerate(definitions): for i, definition in enumerate(definitions):
html += buildVocabDef(definition, i, factQuery) html += buildVocabDef(definition, i, query)
else: else:
html += """ html += """
<p>No definitions to display.</p> <p>No definitions to display.</p>
<p>Mouse over text with the <em>middle mouse button</em> or <em>shift key</em> pressed to search.</p> <p>Mouse over text with the <em>middle mouse button</em> or <em>shift key</em> pressed to search.</p>
<p>You can also also input terms in the search box below.</p>""" <p>You can also also input terms in the search box below.</p>"""
html += '</body></html>' return html + buildDefFooter()
def buildKanjiDef(definition, index, query):
links = '<a href = "copyKanjiDef:{0}"><img src = "://img/img/icon_copy_definition.png" align = "right"/></a>'.format(index)
if query and query('kanji', definition):
links += '<a href = "addKanji:{0}"><img src = "://img/img/icon_add_expression.png" align = "right"/></a>'.format(index)
html = u"""
<span class = "links">{0}</span>
<span class = "character">{1}<br/></span>
<span class = "glossary">{2}<br/></span>
<br clear = "all"/>""".format(links, definition['character'], definition['glossary'])
return html return html
def buildKanjiDefs(definitions, query):
html = buildDefHeader()
if len(definitions) > 0:
for i, definition in enumerate(definitions):
html += buildKanjiDef(definition, i, query)
else:
html += '<p>No definitions to display.</p>'
return html + buildDefFooter()