Some basic support for displaying information about characters
Former-commit-id: 895554df1f912021309091c88cd5b3c2a8b7211f
This commit is contained in:
parent
bd5fe72ab2
commit
d279b2bf28
@ -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,
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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 = ' • '.join(definition['rules'])
|
rules = ' • '.join(definition['rules'])
|
||||||
rules = '<span class = "rules"><{0}><br/></span>'.format(rules)
|
rules = '<span class = "rules"><{0}><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()
|
||||||
|
Loading…
Reference in New Issue
Block a user