1
This commit is contained in:
Alex Yatskov 2011-10-08 09:32:51 -07:00
parent ead20a8d97
commit 2c0058d0e4
7 changed files with 149 additions and 150 deletions

View File

@ -67,45 +67,45 @@ class Preferences:
self.clear()
for general in root.getElementsByTagName('general'):
self.generalRecentLoad = self.__readAttrBool(general, 'recentLoad', self.generalRecentLoad)
self.generalReadingsStrip = self.__readAttrBool(general, 'readingsStrip', self.generalReadingsStrip)
self.generalFindUpdates = self.__readAttrBool(general, 'findUpdates', self.generalFindUpdates)
self.generalRecentLoad = self.readAttrBool(general, 'recentLoad', self.generalRecentLoad)
self.generalReadingsStrip = self.readAttrBool(general, 'readingsStrip', self.generalReadingsStrip)
self.generalFindUpdates = self.readAttrBool(general, 'findUpdates', self.generalFindUpdates)
for recent in general.getElementsByTagName('recent'):
path = self.__readAttrStr(recent, 'path')
position = self.__readAttrInt(recent, 'position')
path = self.readAttrStr(recent, 'path')
position = self.readAttrInt(recent, 'position')
if path and os.path.isfile(path):
self.generalRecentFiles.append((path, position))
for ui in root.getElementsByTagName('ui'):
for content in ui.getElementsByTagName('content'):
self.uiContentFontFamily = self.__readAttrStr(content, 'fontFamily', self.uiContentFontFamily)
self.uiContentFontSize = self.__readAttrInt(content, 'fontSize', self.uiContentFontSize)
self.uiContentColorFg = self.__readAttrInt(content, 'colorFg', self.uiContentColorFg)
self.uiContentColorBg = self.__readAttrInt(content, 'colorBg', self.uiContentColorBg)
self.uiContentWordWrap = self.__readAttrBool(content, 'wordWrap', self.uiContentWordWrap)
self.uiContentFontFamily = self.readAttrStr(content, 'fontFamily', self.uiContentFontFamily)
self.uiContentFontSize = self.readAttrInt(content, 'fontSize', self.uiContentFontSize)
self.uiContentColorFg = self.readAttrInt(content, 'colorFg', self.uiContentColorFg)
self.uiContentColorBg = self.readAttrInt(content, 'colorBg', self.uiContentColorBg)
self.uiContentWordWrap = self.readAttrBool(content, 'wordWrap', self.uiContentWordWrap)
for reader in ui.getElementsByTagName('reader'):
self.uiReaderState = self.__readAttrStr(reader, 'state', self.uiReaderState)
self.uiReaderPosition = self.__readAttrIntTuple(reader, 'position', self.uiReaderPosition)
self.uiReaderSize = self.__readAttrIntTuple(reader, 'size', self.uiReaderSize)
self.uiReaderState = self.readAttrStr(reader, 'state', self.uiReaderState)
self.uiReaderPosition = self.readAttrIntTuple(reader, 'position', self.uiReaderPosition)
self.uiReaderSize = self.readAttrIntTuple(reader, 'size', self.uiReaderSize)
for search in root.getElementsByTagName('search'):
self.searchScanMax = self.__readAttrInt(search, 'scanMax', self.searchScanMax)
self.searchResultMax = self.__readAttrInt(search, 'resultMax', self.searchResultMax)
self.searchGroupByExp = self.__readAttrBool(search, 'groupByExp', self.searchGroupByExp)
self.searchScanMax = self.readAttrInt(search, 'scanMax', self.searchScanMax)
self.searchResultMax = self.readAttrInt(search, 'resultMax', self.searchResultMax)
self.searchGroupByExp = self.readAttrBool(search, 'groupByExp', self.searchGroupByExp)
for anki in root.getElementsByTagName('anki'):
self.ankiShowIcon = self.__readAttrBool(anki, 'showIcon', self.ankiShowIcon)
self.ankiShowIcon = self.readAttrBool(anki, 'showIcon', self.ankiShowIcon)
for tag in anki.getElementsByTagName('tag'):
value = self.__readAttrStr(tag, 'value', unicode())
value = self.readAttrStr(tag, 'value', unicode())
self.ankiTags.append(value)
for model in anki.getElementsByTagName('model'):
for field in model.getElementsByTagName('field'):
name = self.__readAttrStr(field, 'name')
value = self.__readAttrStr(field, 'value')
name = self.readAttrStr(field, 'name')
value = self.readAttrStr(field, 'value')
if name and value:
self.ankiFields[name] = value
@ -129,46 +129,46 @@ class Preferences:
general = doc.createElement('general')
root.appendChild(general)
self.__writeAttrBool(general, 'recentLoad', self.generalRecentLoad)
self.__writeAttrBool(general, 'readingsStrip', self.generalReadingsStrip)
self.__writeAttrBool(general, 'findUpdates', self.generalFindUpdates)
self.writeAttrBool(general, 'recentLoad', self.generalRecentLoad)
self.writeAttrBool(general, 'readingsStrip', self.generalReadingsStrip)
self.writeAttrBool(general, 'findUpdates', self.generalFindUpdates)
for path, position in self.generalRecentFiles:
recent = doc.createElement('recent')
general.appendChild(recent)
self.__writeAttrStr(recent, 'path', path)
self.__writeAttrInt(recent, 'position', position)
self.writeAttrStr(recent, 'path', path)
self.writeAttrInt(recent, 'position', position)
ui = doc.createElement('ui')
root.appendChild(ui)
content = doc.createElement('content')
ui.appendChild(content)
self.__writeAttrStr(content, 'fontFamily', self.uiContentFontFamily)
self.__writeAttrInt(content, 'fontSize', self.uiContentFontSize)
self.__writeAttrInt(content, 'colorFg', self.uiContentColorFg)
self.__writeAttrInt(content, 'colorBg', self.uiContentColorBg)
self.__writeAttrBool(content, 'wordWrap', self.uiContentWordWrap)
self.writeAttrStr(content, 'fontFamily', self.uiContentFontFamily)
self.writeAttrInt(content, 'fontSize', self.uiContentFontSize)
self.writeAttrInt(content, 'colorFg', self.uiContentColorFg)
self.writeAttrInt(content, 'colorBg', self.uiContentColorBg)
self.writeAttrBool(content, 'wordWrap', self.uiContentWordWrap)
reader = doc.createElement('reader')
ui.appendChild(reader)
self.__writeAttrStr(reader, 'state', self.uiReaderState)
self.__writeAttrIntTuple(reader, 'position', self.uiReaderPosition)
self.__writeAttrIntTuple(reader, 'size', self.uiReaderSize)
self.writeAttrStr(reader, 'state', self.uiReaderState)
self.writeAttrIntTuple(reader, 'position', self.uiReaderPosition)
self.writeAttrIntTuple(reader, 'size', self.uiReaderSize)
search = doc.createElement('search')
root.appendChild(search)
self.__writeAttrInt(search, 'scanMax', self.searchScanMax)
self.__writeAttrInt(search, 'resultMax', self.searchResultMax)
self.__writeAttrBool(search, 'groupByExp', self.searchGroupByExp)
self.writeAttrInt(search, 'scanMax', self.searchScanMax)
self.writeAttrInt(search, 'resultMax', self.searchResultMax)
self.writeAttrBool(search, 'groupByExp', self.searchGroupByExp)
anki = doc.createElement('anki')
root.appendChild(anki)
self.__writeAttrBool(anki, 'showIcon', self.ankiShowIcon)
self.writeAttrBool(anki, 'showIcon', self.ankiShowIcon)
for value in self.ankiTags:
tag = doc.createElement('tag')
anki.appendChild(tag)
self.__writeAttrStr(tag, 'value', value)
self.writeAttrStr(tag, 'value', value)
if self.ankiFields:
model = doc.createElement('model')
@ -176,8 +176,8 @@ class Preferences:
for name, value in self.ankiFields.items():
field = doc.createElement('field')
model.appendChild(field)
self.__writeAttrStr(field, 'name', name)
self.__writeAttrStr(field, 'value', value)
self.writeAttrStr(field, 'name', name)
self.writeAttrStr(field, 'value', value)
try:
with open(filename, 'w') as fp:
@ -217,40 +217,40 @@ class Preferences:
self.generalRecentFiles = list()
def __readAttrStr(self, node, name, default=None):
def readAttrStr(self, node, name, default=None):
return node.getAttribute(name) or default
def __readAttrBool(self, node, name, default=False):
value = self.__readAttrStr(node, name)
def readAttrBool(self, node, name, default=False):
value = self.readAttrStr(node, name)
return value.lower() == 'true' if value else default
def __readAttrInt(self, node, name, default=0):
value = self.__readAttrStr(node, name)
def readAttrInt(self, node, name, default=0):
value = self.readAttrStr(node, name)
return int(value) if value else default
def __readAttrIntTuple(self, node, name, default=None):
value = self.__readAttrStr(node, name)
def readAttrIntTuple(self, node, name, default=None):
value = self.readAttrStr(node, name)
return tuple([int(v) for v in value.split(',')]) if value else default
def __writeAttrStr(self, node, name, value):
def writeAttrStr(self, node, name, value):
if value != None:
node.setAttribute(name, value)
def __writeAttrBool(self, node, name, value):
def writeAttrBool(self, node, name, value):
if value != None:
node.setAttribute(name, ['false', 'true'][bool(value)])
def __writeAttrInt(self, node, name, value):
def writeAttrInt(self, node, name, value):
if value != None:
node.setAttribute(name, str(value))
def __writeAttrIntTuple(self, node, name, value):
def writeAttrIntTuple(self, node, name, value):
if value != None:
node.setAttribute(name, ','.join([str(v) for v in value]))

View File

@ -25,69 +25,69 @@ class DialogPreferences(QtGui.QDialog, Ui_DialogPreferences):
self.setupUi(self)
bindings = [
(self, 'accepted()', self.__onAccept),
(self.buttonContentColorFg, 'clicked()', self.__onButtonColorFgClicked),
(self.buttonContentColorBg, 'clicked()', self.__onButtonColorBgClicked),
(self.comboContentFontFamily, 'currentFontChanged(const QFont&)', self.__onFontFamilyChanged),
(self.spinContentFontSize, 'valueChanged(int)', self.__onFontSizeChanged)
(self, 'accepted()', self.onAccept),
(self.buttonContentColorFg, 'clicked()', self.onButtonColorFgClicked),
(self.buttonContentColorBg, 'clicked()', self.onButtonColorBgClicked),
(self.comboContentFontFamily, 'currentFontChanged(const QFont&)', self.onFontFamilyChanged),
(self.spinContentFontSize, 'valueChanged(int)', self.onFontSizeChanged)
]
for action, signal, callback in bindings:
self.connect(action, QtCore.SIGNAL(signal), callback)
self.__preferences = preferences
self.__anki = anki
self.preferences = preferences
self.anki = anki
self.__dataToDialog()
self.dataToDialog()
def __dataToDialog(self):
self.checkGeneralRecentLoad.setChecked(self.__preferences.generalRecentLoad)
self.checkGeneralReadingsStrip.setChecked(self.__preferences.generalReadingsStrip)
self.checkGeneralFindUpdates.setChecked(self.__preferences.generalFindUpdates)
def dataToDialog(self):
self.checkGeneralRecentLoad.setChecked(self.preferences.generalRecentLoad)
self.checkGeneralReadingsStrip.setChecked(self.preferences.generalReadingsStrip)
self.checkGeneralFindUpdates.setChecked(self.preferences.generalFindUpdates)
self.__updateSampleText()
self.updateSampleText()
font = self.textContentSample.font()
self.comboContentFontFamily.setCurrentFont(font)
self.spinContentFontSize.setValue(font.pointSize())
self.spinSearchScanMax.setValue(self.__preferences.searchScanMax)
self.spinSearchResultMax.setValue(self.__preferences.searchResultMax)
self.checkSearchGroupByExp.setChecked(self.__preferences.searchGroupByExp)
self.spinSearchScanMax.setValue(self.preferences.searchScanMax)
self.spinSearchResultMax.setValue(self.preferences.searchResultMax)
self.checkSearchGroupByExp.setChecked(self.preferences.searchGroupByExp)
self.checkAnkiShowIcon.setChecked(self.__preferences.ankiShowIcon)
self.tabAnki.setEnabled(bool(self.__anki))
if self.__anki:
self.__setAnkiFields(self.__anki.fields(), self.__preferences.ankiFields)
self.checkAnkiShowIcon.setChecked(self.preferences.ankiShowIcon)
self.tabAnki.setEnabled(bool(self.anki))
if self.anki:
self.setAnkiFields(self.anki.fields(), self.preferences.ankiFields)
def __dialogToData(self):
self.__preferences.generalRecentLoad = self.checkGeneralRecentLoad.isChecked()
self.__preferences.generalReadingsStrip = self.checkGeneralReadingsStrip.isChecked()
self.__preferences.generalFindUpdates = self.checkGeneralFindUpdates.isChecked()
def dialogToData(self):
self.preferences.generalRecentLoad = self.checkGeneralRecentLoad.isChecked()
self.preferences.generalReadingsStrip = self.checkGeneralReadingsStrip.isChecked()
self.preferences.generalFindUpdates = self.checkGeneralFindUpdates.isChecked()
self.__preferences.searchScanMax = self.spinSearchScanMax.value()
self.__preferences.searchResultMax = self.spinSearchResultMax.value()
self.__preferences.searchGroupByExp = self.checkSearchGroupByExp.isChecked()
self.preferences.searchScanMax = self.spinSearchScanMax.value()
self.preferences.searchResultMax = self.spinSearchResultMax.value()
self.preferences.searchGroupByExp = self.checkSearchGroupByExp.isChecked()
self.__preferences.ankiShowIcon = self.checkAnkiShowIcon.isChecked()
if self.__anki:
self.__preferences.ankiFields = self.__ankiFields()
self.preferences.ankiShowIcon = self.checkAnkiShowIcon.isChecked()
if self.anki:
self.preferences.ankiFields = self.ankiFields()
def __updateSampleText(self):
def updateSampleText(self):
palette = self.textContentSample.palette()
palette.setColor(QtGui.QPalette.Base, QtGui.QColor(self.__preferences.uiContentColorBg))
palette.setColor(QtGui.QPalette.Text, QtGui.QColor(self.__preferences.uiContentColorFg))
palette.setColor(QtGui.QPalette.Base, QtGui.QColor(self.preferences.uiContentColorBg))
palette.setColor(QtGui.QPalette.Text, QtGui.QColor(self.preferences.uiContentColorFg))
self.textContentSample.setPalette(palette)
font = self.textContentSample.font()
font.setFamily(self.__preferences.uiContentFontFamily)
font.setPointSize(self.__preferences.uiContentFontSize)
font.setFamily(self.preferences.uiContentFontFamily)
font.setPointSize(self.preferences.uiContentFontSize)
self.textContentSample.setFont(font)
def __setAnkiFields(self, fieldsAnki, fieldsPrefs):
def setAnkiFields(self, fieldsAnki, fieldsPrefs):
self.tableAnkiFields.setRowCount(len(fieldsAnki))
for i, (name, required, unique) in enumerate(fieldsAnki):
@ -114,7 +114,7 @@ class DialogPreferences(QtGui.QDialog, Ui_DialogPreferences):
self.tableAnkiFields.setItem(i, j, column)
def __ankiFields(self):
def ankiFields(self):
result = dict()
for i in range(0, self.tableAnkiFields.rowCount()):
@ -125,29 +125,29 @@ class DialogPreferences(QtGui.QDialog, Ui_DialogPreferences):
return result
def __onAccept(self):
self.__dialogToData()
def onAccept(self):
self.dialogToData()
def __onButtonColorFgClicked(self):
color, ok = QtGui.QColorDialog.getRgba(self.__preferences.uiContentColorFg, self)
def onButtonColorFgClicked(self):
color, ok = QtGui.QColorDialog.getRgba(self.preferences.uiContentColorFg, self)
if ok:
self.__preferences.uiContentColorFg = color
self.__updateSampleText()
self.preferences.uiContentColorFg = color
self.updateSampleText()
def __onButtonColorBgClicked(self):
color, ok = QtGui.QColorDialog.getRgba(self.__preferences.uiContentColorBg, self)
def onButtonColorBgClicked(self):
color, ok = QtGui.QColorDialog.getRgba(self.preferences.uiContentColorBg, self)
if ok:
self.__preferences.uiContentColorBg = color
self.__updateSampleText()
self.preferences.uiContentColorBg = color
self.updateSampleText()
def __onFontFamilyChanged(self, font):
self.__preferences.uiContentFontFamily = font.family()
self.__updateSampleText()
def onFontFamilyChanged(self, font):
self.preferences.uiContentFontFamily = font.family()
self.updateSampleText()
def __onFontSizeChanged(self, size):
self.__preferences.uiContentFontSize = size
self.__updateSampleText()
def onFontSizeChanged(self, size):
self.preferences.uiContentFontSize = size
self.updateSampleText()

View File

@ -21,12 +21,12 @@ from deinflect import Deinflector
from translate import Translator
def __buildRelPath(path):
def buildRelPath(path):
directory = os.path.split(__file__)[0]
return os.path.join(directory, path)
def initLanguage():
deinflector = Deinflector(__buildRelPath('data/deinflect.dat'))
dictionary = Dictionary(__buildRelPath('data/dict.sqlite'))
deinflector = Deinflector(buildRelPath('data/deinflect.dat'))
dictionary = Dictionary(buildRelPath('data/dict.sqlite'))
return Translator(deinflector, dictionary)

View File

@ -20,7 +20,7 @@ import codecs
class Deinflector:
class __Rule:
class Rule:
def __init__(self, source, target, types, reason):
self.source = unicode(source)
self.target = unicode(target)
@ -28,7 +28,7 @@ class Deinflector:
self.reason = int(reason)
class __Result:
class Result:
def __init__(self, stem, types, conjugations):
self.stem = unicode(stem)
self.types = int(types)
@ -43,8 +43,8 @@ class Deinflector:
def close(self):
self.__conjugations = list()
self.__rules = dict()
self.conjugations = list()
self.rules = dict()
def load(self, filename):
@ -63,13 +63,13 @@ class Deinflector:
fieldCount = len(fields)
if fieldCount == 1:
self.__conjugations.append(fields[0])
self.conjugations.append(fields[0])
elif fieldCount == 4:
rule = self.__Rule(*fields)
rule = self.Rule(*fields)
sourceLength = len(rule.source)
if sourceLength not in self.__rules:
self.__rules[sourceLength] = list()
self.__rules[sourceLength].append(rule)
if sourceLength not in self.rules:
self.rules[sourceLength] = list()
self.rules[sourceLength].append(rule)
else:
self.close()
return False
@ -78,11 +78,11 @@ class Deinflector:
def deinflect(self, word):
results = [self.__Result(word, 0xff, list())]
results = [self.Result(word, 0xff, list())]
have = {word: 0}
for result in results:
for length, group in sorted(self.__rules.items(), reverse=True):
for length, group in sorted(self.rules.items(), reverse=True):
if length > len(result.stem):
continue
@ -101,8 +101,8 @@ class Deinflector:
have[new] = len(results)
conjugations = [self.__conjugations[rule.reason]] + result.conjugations
results.append(self.__Result(new, rule.types >> 8, conjugations))
conjugations = [self.conjugations[rule.reason]] + result.conjugations
results.append(self.Result(new, rule.types >> 8, conjugations))
return [
(result.stem, u', '.join(result.conjugations), result.types) for result in results

View File

@ -28,20 +28,20 @@ class Dictionary:
def close(self):
self.__connection = None
self.connection = None
def load(self, filename):
self.__connection = sqlite3.connect(filename)
self.connection = sqlite3.connect(filename)
def __find(self, exp, args):
if self.__connection == None:
def find(self, exp, args):
if self.connection == None:
return list()
entries = list()
for kanji, kana, entry in self.__connection.cursor().execute(exp, args):
for kanji, kana, entry in self.connection.cursor().execute(exp, args):
meanings = entry.split('/')
if not meanings[-1]:
@ -62,4 +62,4 @@ class Dictionary:
def findWord(self, word):
return self.__find(u'select * from dict where kanji=? or kana=? limit 100', (word,) * 2)
return self.find(u'select * from dict where kanji=? or kana=? limit 100', (word,) * 2)

View File

@ -22,26 +22,26 @@ from operator import itemgetter
class Translator:
def __init__(self, deinflector, dictionary):
self.__deinflector = deinflector
self.__dictionary = dictionary
self.deinflector = deinflector
self.dictionary = dictionary
def wordSearch(self, word, limit, group):
source, indices = self.__convertKatakana(word)
source, indices = self.convertKatakana(word)
groups = dict()
length = 0
count = 0
while source:
for i, (stem, conjugations, types) in enumerate(self.__deinflector.deinflect(source)):
for expression, reading, glossary in self.__dictionary.findWord(stem):
for i, (stem, conjugations, types) in enumerate(self.deinflector.deinflect(source)):
for expression, reading, glossary in self.dictionary.findWord(stem):
if count >= limit:
break
if i > 0:
tags = re.split('[,()]', glossary)
if not self.__deinflector.validate(types, tags):
if not self.deinflector.validate(types, tags):
continue
length = max(length, indices[len(source) - 1] + 1)
@ -77,7 +77,7 @@ class Translator:
return results, length
def __convertKatakana(self, word):
def convertKatakana(self, word):
kanaHalf = [
0x3092, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049, 0x3083, 0x3085,
0x3087, 0x3063, 0x30fc, 0x3042, 0x3044, 0x3046, 0x3048, 0x304a,
@ -135,4 +135,3 @@ class Translator:
ordPrev = ord(char)
return result, indices

View File

@ -36,13 +36,13 @@ class YomichanPlugin:
self.separator.setSeparator(True)
self.action = QtGui.QAction(QtGui.QIcon(':/logos/logos/logo32x32.png'), '&Yomichan...', self.parent)
self.action.setIconVisibleInMenu(True)
self.parent.connect(self.action, QtCore.SIGNAL('triggered()'), self.__onShowRequest)
self.parent.connect(self.action, QtCore.SIGNAL('triggered()'), self.onShowRequest)
self.anki.addHook('loadDeck', self.__onDeckLoad)
self.anki.addHook('deckClosed', self.__onDeckClose)
self.anki.addHook('loadDeck', self.onDeckLoad)
self.anki.addHook('deckClosed', self.onDeckClose)
def __onShowRequest(self):
def onShowRequest(self):
if self.window:
self.window.setVisible(True)
self.window.activateWindow()
@ -53,49 +53,49 @@ class YomichanPlugin:
None,
self.preferences,
self.anki,
self.__onWindowClose,
self.__onWindowUpdate
self.onWindowClose,
self.onWindowUpdate
)
self.window.show()
def __onWindowClose(self):
def onWindowClose(self):
self.window = None
def __onWindowUpdate(self):
def onWindowUpdate(self):
if self.preferences.ankiShowIcon:
self.__showToolIcon()
self.showToolIcon()
else:
self.__hideToolIcon()
self.hideToolIcon()
def __onDeckLoad(self):
def onDeckLoad(self):
self.anki.toolsMenu().addAction(self.separator)
self.anki.toolsMenu().addAction(self.action)
if self.preferences.ankiShowIcon:
self.__showToolIcon()
self.showToolIcon()
def __onDeckClose(self):
def onDeckClose(self):
self.anki.toolsMenu().removeAction(self.action)
self.anki.toolsMenu().removeAction(self.separator)
self.__hideToolIcon()
self.hideToolIcon()
if self.window:
self.window.close()
self.window = None
def __hideToolIcon(self):
def hideToolIcon(self):
if self.toolIconVisible:
self.anki.toolBar().removeAction(self.action)
self.toolIconVisible = False
def __showToolIcon(self):
def showToolIcon(self):
if not self.toolIconVisible:
self.anki.toolBar().addAction(self.action)
self.toolIconVisible = True