mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
start of tags/groups; be more selective in drop accept/deny
This commit is contained in:
parent
ea515a5141
commit
5a2ee8f30e
3 changed files with 202 additions and 327 deletions
500
aqt/editor.py
500
aqt/editor.py
|
@ -120,6 +120,20 @@ function setFields(fields) {
|
||||||
$("#fields").html("<table cellpadding=3>"+txt+"</table>");
|
$("#fields").html("<table cellpadding=3>"+txt+"</table>");
|
||||||
$("#f0").focus();
|
$("#f0").focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
// ignore drops outside the editable area
|
||||||
|
document.body.ondragover = function () {
|
||||||
|
e = window.event.srcElement;
|
||||||
|
do {
|
||||||
|
if (e.contentEditable == "true") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e = window.parentNode;
|
||||||
|
} while (e);
|
||||||
|
window.event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
</script></head><body>
|
</script></head><body>
|
||||||
<div id="fields"></div>
|
<div id="fields"></div>
|
||||||
</body></html>
|
</body></html>
|
||||||
|
@ -170,6 +184,22 @@ class Editor(object):
|
||||||
self.widget.setLayout(l)
|
self.widget.setLayout(l)
|
||||||
self.outerLayout = l
|
self.outerLayout = l
|
||||||
|
|
||||||
|
def setupWeb(self):
|
||||||
|
self.web = AnkiWebView(self.widget)
|
||||||
|
self.web.allowDrops = True
|
||||||
|
self.web.setBridge(self.bridge)
|
||||||
|
self.outerLayout.addWidget(self.web)
|
||||||
|
# pick up the window colour
|
||||||
|
p = self.web.palette()
|
||||||
|
p.setBrush(QPalette.Base, Qt.transparent)
|
||||||
|
self.web.page().setPalette(p)
|
||||||
|
self.web.setAttribute(Qt.WA_OpaquePaintEvent, False)
|
||||||
|
self.web.setHtml(_html % anki.js.all,
|
||||||
|
loadCB=self._loadFinished)
|
||||||
|
|
||||||
|
# Top buttons
|
||||||
|
######################################################################
|
||||||
|
|
||||||
def _addButton(self, name, func, key=None, tip=None, size=True, text="",
|
def _addButton(self, name, func, key=None, tip=None, size=True, text="",
|
||||||
check=False):
|
check=False):
|
||||||
b = QPushButton(text)
|
b = QPushButton(text)
|
||||||
|
@ -190,7 +220,6 @@ class Editor(object):
|
||||||
b.setToolTip(tip)
|
b.setToolTip(tip)
|
||||||
if check:
|
if check:
|
||||||
b.setCheckable(True)
|
b.setCheckable(True)
|
||||||
|
|
||||||
self.iconsBox.addWidget(b)
|
self.iconsBox.addWidget(b)
|
||||||
self._buttons[name] = b
|
self._buttons[name] = b
|
||||||
return b
|
return b
|
||||||
|
@ -243,17 +272,33 @@ class Editor(object):
|
||||||
hbox.setMargin(5)
|
hbox.setMargin(5)
|
||||||
but.setLayout(hbox)
|
but.setLayout(hbox)
|
||||||
|
|
||||||
def setupWeb(self):
|
def enableButtons(self, val=True):
|
||||||
self.web = AnkiWebView(self.widget)
|
self.bold.setEnabled(val)
|
||||||
self.web.setBridge(self.bridge)
|
self.italic.setEnabled(val)
|
||||||
self.outerLayout.addWidget(self.web)
|
self.underline.setEnabled(val)
|
||||||
# pick up the window colour
|
self.foreground.setEnabled(val)
|
||||||
p = self.web.palette()
|
self.addPicture.setEnabled(val)
|
||||||
p.setBrush(QPalette.Base, Qt.transparent)
|
self.addSound.setEnabled(val)
|
||||||
self.web.page().setPalette(p)
|
self.latex.setEnabled(val)
|
||||||
self.web.setAttribute(Qt.WA_OpaquePaintEvent, False)
|
self.latexEqn.setEnabled(val)
|
||||||
self.web.setHtml(_html % anki.js.all,
|
self.latexMathEnv.setEnabled(val)
|
||||||
loadCB=self._loadFinished)
|
self.cloze.setEnabled(val)
|
||||||
|
self.htmlEdit.setEnabled(val)
|
||||||
|
self.recSound.setEnabled(val)
|
||||||
|
|
||||||
|
def disableButtons(self):
|
||||||
|
self.enableButtons(False)
|
||||||
|
|
||||||
|
def onCardLayout(self):
|
||||||
|
from aqt.clayout import CardLayout
|
||||||
|
if self.card:
|
||||||
|
type = 1; ord = self.card.ord
|
||||||
|
else:
|
||||||
|
type = 0; ord = 0
|
||||||
|
CardLayout(self.mw, self.fact, type=type, ord=ord, parent=self.widget)
|
||||||
|
|
||||||
|
# JS->Python bridge
|
||||||
|
######################################################################
|
||||||
|
|
||||||
def bridge(self, str):
|
def bridge(self, str):
|
||||||
print str
|
print str
|
||||||
|
@ -301,41 +346,14 @@ class Editor(object):
|
||||||
txt, "{{c%d::%s}}" % (next, txt))
|
txt, "{{c%d::%s}}" % (next, txt))
|
||||||
self.loadFact()
|
self.loadFact()
|
||||||
|
|
||||||
|
# Setting/unsetting the current fact
|
||||||
|
######################################################################
|
||||||
|
|
||||||
def _loadFinished(self, w):
|
def _loadFinished(self, w):
|
||||||
self._loaded = True
|
self._loaded = True
|
||||||
if self.fact:
|
if self.fact:
|
||||||
self.loadFact()
|
self.loadFact()
|
||||||
|
|
||||||
def setupTags(self):
|
|
||||||
return
|
|
||||||
# # scrollarea
|
|
||||||
# self.fieldsScroll = QScrollArea()
|
|
||||||
# self.fieldsScroll.setWidgetResizable(True)
|
|
||||||
# self.fieldsScroll.setLineWidth(0)
|
|
||||||
# self.fieldsScroll.setFrameStyle(0)
|
|
||||||
# self.fieldsScroll.setFocusPolicy(Qt.NoFocus)
|
|
||||||
# self.fieldsBox.addWidget(self.fieldsScroll)
|
|
||||||
# # tags
|
|
||||||
# self.tagsBox = QHBoxLayout()
|
|
||||||
# self.tagsLabel = QLabel(_("Tags"))
|
|
||||||
# self.tagsBox.addWidget(self.tagsLabel)
|
|
||||||
# import aqt.tagedit
|
|
||||||
# self.tags = aqt.tagedit.TagEdit(self.parent)
|
|
||||||
# self.tags.connect(self.tags, SIGNAL("lostFocus"),
|
|
||||||
# self.onTagChange)
|
|
||||||
# self.tagsBox.addWidget(self.tags)
|
|
||||||
# self.fieldsBox.addLayout(self.tagsBox)
|
|
||||||
|
|
||||||
# update available tags
|
|
||||||
self.tags.setDeck(self.deck)
|
|
||||||
tagsw = self.tagsLabel.sizeHint().width()
|
|
||||||
self.tagsLabel.setFixedWidth(max(tagsw,
|
|
||||||
max(*([
|
|
||||||
l.width() for l in self.labels] + [0])))
|
|
||||||
+ extra)
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def setFact(self, fact):
|
def setFact(self, fact):
|
||||||
"Make FACT the current fact."
|
"Make FACT the current fact."
|
||||||
self.fact = fact
|
self.fact = fact
|
||||||
|
@ -344,6 +362,7 @@ class Editor(object):
|
||||||
self.changeTimer = None
|
self.changeTimer = None
|
||||||
if self.fact:
|
if self.fact:
|
||||||
self.loadFact()
|
self.loadFact()
|
||||||
|
self.updateTags()
|
||||||
else:
|
else:
|
||||||
self.widget.hide()
|
self.widget.hide()
|
||||||
|
|
||||||
|
@ -361,9 +380,6 @@ class Editor(object):
|
||||||
# fixme: what if fact is deleted?
|
# fixme: what if fact is deleted?
|
||||||
self.setFact(self.fact)
|
self.setFact(self.fact)
|
||||||
|
|
||||||
def initMedia(self):
|
|
||||||
os.chdir(self.deck.mediaDir(create=True))
|
|
||||||
|
|
||||||
def deckClosedHook(self):
|
def deckClosedHook(self):
|
||||||
self.setFact(None)
|
self.setFact(None)
|
||||||
|
|
||||||
|
@ -381,93 +397,9 @@ class Editor(object):
|
||||||
lambda w=w: self.formatChanged(w))
|
lambda w=w: self.formatChanged(w))
|
||||||
return w
|
return w
|
||||||
|
|
||||||
def loadFields(self, check=True, font=True):
|
|
||||||
"Update field text (if changed) and font/colours."
|
|
||||||
# text
|
|
||||||
for field in self.fact.fields:
|
|
||||||
w = self.fields[field.name][1]
|
|
||||||
self.fields[field.name] = (field, w)
|
|
||||||
self.widgets[w] = field
|
|
||||||
new = self.fact[field.name]
|
|
||||||
#old = tidyHTML(unicode(w.toHtml()))
|
|
||||||
# only update if something has changed
|
|
||||||
if new != old:
|
|
||||||
cur = w.textCursor()
|
|
||||||
w.setHtml('<meta name="qrichtext" content="1"/>' + new)
|
|
||||||
w.setTextCursor(cur)
|
|
||||||
if font:
|
|
||||||
# apply fonts
|
|
||||||
font = QFont()
|
|
||||||
# family
|
|
||||||
family = field.fieldModel.quizFontFamily
|
|
||||||
if family:
|
|
||||||
font.setFamily(family)
|
|
||||||
# size
|
|
||||||
size = field.fieldModel.editFontSize
|
|
||||||
if size:
|
|
||||||
font.setPixelSize(size)
|
|
||||||
w.setFont(font)
|
|
||||||
self.tags.blockSignals(True)
|
|
||||||
self.tags.setText(self.fact.tags)
|
|
||||||
self.tags.blockSignals(False)
|
|
||||||
if check:
|
if check:
|
||||||
self.checkValid()
|
self.checkValid()
|
||||||
|
|
||||||
def saveFields(self):
|
|
||||||
"Save field text into fact."
|
|
||||||
modified = False
|
|
||||||
n = _("Edit")
|
|
||||||
self.deck.setUndoStart(n, merge=True)
|
|
||||||
for (w, f) in self.widgets.items():
|
|
||||||
#v = tidyHTML(unicode(w.toHtml()))
|
|
||||||
if self.fact[f.name] != v:
|
|
||||||
self.fact[f.name] = v
|
|
||||||
modified = True
|
|
||||||
if modified:
|
|
||||||
self.fact.setModified(textChanged=True, deck=self.deck)
|
|
||||||
if not self.fact.isNew():
|
|
||||||
self.deck.setModified()
|
|
||||||
self.deck.setUndoEnd(n)
|
|
||||||
return modified
|
|
||||||
|
|
||||||
def onFocusLost(self, widget):
|
|
||||||
from aqt import mw
|
|
||||||
if not self.fact:
|
|
||||||
# editor or deck closed
|
|
||||||
return
|
|
||||||
if mw.inDbHandler:
|
|
||||||
return
|
|
||||||
modified = self.saveFields()
|
|
||||||
field = self.widgets[widget]
|
|
||||||
self.fact.focusLost(field)
|
|
||||||
self.fact.setModified(textChanged=True, deck=self.deck)
|
|
||||||
self.loadFields(font=False)
|
|
||||||
if modified:
|
|
||||||
self.mw.reset(runHooks=False)
|
|
||||||
|
|
||||||
def onTextChanged(self):
|
|
||||||
interval = 250
|
|
||||||
if self.changeTimer:
|
|
||||||
self.changeTimer.setInterval(interval)
|
|
||||||
else:
|
|
||||||
self.changeTimer = QTimer(self.parent)
|
|
||||||
self.changeTimer.setSingleShot(True)
|
|
||||||
self.changeTimer.start(interval)
|
|
||||||
self.parent.connect(self.changeTimer,
|
|
||||||
SIGNAL("timeout()"),
|
|
||||||
self.onChangeTimer)
|
|
||||||
|
|
||||||
def onChangeTimer(self):
|
|
||||||
from aqt import mw
|
|
||||||
interval = 250
|
|
||||||
if not self.fact:
|
|
||||||
return
|
|
||||||
if mw.inDbHandler:
|
|
||||||
self.changeTimer.start(interval)
|
|
||||||
return
|
|
||||||
self.checkValid()
|
|
||||||
self.changeTimer = None
|
|
||||||
|
|
||||||
def saveFieldsNow(self):
|
def saveFieldsNow(self):
|
||||||
"Must call this before adding cards, closing dialog, etc."
|
"Must call this before adding cards, closing dialog, etc."
|
||||||
if not self.fact:
|
if not self.fact:
|
||||||
|
@ -504,26 +436,59 @@ class Editor(object):
|
||||||
p.setColor(QPalette.Base, QColor("#ffffff"))
|
p.setColor(QPalette.Base, QColor("#ffffff"))
|
||||||
self.fields[field.name][1].setPalette(p)
|
self.fields[field.name][1].setPalette(p)
|
||||||
|
|
||||||
def textForField(self, field):
|
def onHtmlEdit(self):
|
||||||
"Current edited value for field."
|
def helpRequested():
|
||||||
w = self.fields[field.name][1]
|
aqt.openHelp("HtmlEditor")
|
||||||
#v = tidyHTML(unicode(w.toHtml()))
|
w = self.focusedEdit()
|
||||||
return v
|
if w:
|
||||||
|
self.saveFields()
|
||||||
|
d = QDialog(self.widget)
|
||||||
|
form = aqt.forms.edithtml.Ui_Dialog()
|
||||||
|
form.setupUi(d)
|
||||||
|
d.connect(form.buttonBox, SIGNAL("helpRequested()"),
|
||||||
|
helpRequested)
|
||||||
|
form.textEdit.setPlainText(self.widgets[w].value)
|
||||||
|
form.textEdit.moveCursor(QTextCursor.End)
|
||||||
|
d.exec_()
|
||||||
|
w.setHtml(unicode(form.textEdit.toPlainText()).\
|
||||||
|
replace("\n", ""))
|
||||||
|
self.saveFields()
|
||||||
|
|
||||||
def fieldValid(self, field):
|
# Tag and group handling
|
||||||
return not (field.fieldModel.required and
|
######################################################################
|
||||||
not self.textForField(field).strip())
|
|
||||||
|
|
||||||
def fieldUnique(self, field):
|
def setupTags(self):
|
||||||
if not field.fieldModel.unique:
|
import aqt.tagedit
|
||||||
return True
|
g = QGroupBox(self.widget)
|
||||||
req = ("select value from fields "
|
tb = QGridLayout()
|
||||||
"where fieldModelId = :fmid and value = :val and id != :id "
|
tb.setSpacing(12)
|
||||||
"and chksum = :chk")
|
tb.setMargin(6)
|
||||||
val = self.textForField(field)
|
# group
|
||||||
return not self.deck.db.scalar(
|
l = QLabel(_("Group"))
|
||||||
req, val=val, fmid=field.fieldModel.id,
|
tb.addWidget(l, 0, 0)
|
||||||
id=field.id, chk=fieldChecksum(val))
|
self.group = aqt.tagedit.TagEdit(self.widget, type=1)
|
||||||
|
self.group.connect(self.group, SIGNAL("lostFocus"),
|
||||||
|
self.onGroupChange)
|
||||||
|
tb.addWidget(self.group, 0, 1)
|
||||||
|
# tags
|
||||||
|
l = QLabel(_("Tags"))
|
||||||
|
tb.addWidget(l, 1, 0)
|
||||||
|
self.tags = aqt.tagedit.TagEdit(self.widget)
|
||||||
|
self.tags.connect(self.tags, SIGNAL("lostFocus"),
|
||||||
|
self.onTagChange)
|
||||||
|
tb.addWidget(self.tags, 1, 1)
|
||||||
|
g.setLayout(tb)
|
||||||
|
self.outerLayout.addWidget(g)
|
||||||
|
|
||||||
|
def updateTags(self):
|
||||||
|
if self.tags.deck != self.mw.deck:
|
||||||
|
self.tags.setDeck(self.mw.deck)
|
||||||
|
self.group.setDeck(self.mw.deck)
|
||||||
|
self.group.setText(self.mw.deck.groupName(
|
||||||
|
self.fact.model().conf['gid']))
|
||||||
|
|
||||||
|
def onGroupChange(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def onTagChange(self):
|
def onTagChange(self):
|
||||||
if not self.fact:
|
if not self.fact:
|
||||||
|
@ -539,51 +504,8 @@ class Editor(object):
|
||||||
if self.onChange:
|
if self.onChange:
|
||||||
self.onChange('tag')
|
self.onChange('tag')
|
||||||
|
|
||||||
def focusField(self, fieldName):
|
# Format buttons
|
||||||
self.fields[fieldName][1].setFocus()
|
######################################################################
|
||||||
|
|
||||||
def formatChanged(self, fmt):
|
|
||||||
w = self.focusedEdit()
|
|
||||||
if not w:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
l = self.bold, self.italic, self.underline
|
|
||||||
for b in l:
|
|
||||||
b.blockSignals(True)
|
|
||||||
self.bold.setChecked(w.fontWeight() == QFont.Bold)
|
|
||||||
self.italic.setChecked(w.fontItalic())
|
|
||||||
self.underline.setChecked(w.fontUnderline())
|
|
||||||
for b in l:
|
|
||||||
b.blockSignals(False)
|
|
||||||
|
|
||||||
def resetFormatButtons(self):
|
|
||||||
for b in self.bold, self.italic, self.underline:
|
|
||||||
b.blockSignals(True)
|
|
||||||
b.setChecked(False)
|
|
||||||
b.blockSignals(False)
|
|
||||||
|
|
||||||
def enableButtons(self, val=True):
|
|
||||||
self.bold.setEnabled(val)
|
|
||||||
self.italic.setEnabled(val)
|
|
||||||
self.underline.setEnabled(val)
|
|
||||||
self.foreground.setEnabled(val)
|
|
||||||
self.addPicture.setEnabled(val)
|
|
||||||
self.addSound.setEnabled(val)
|
|
||||||
self.latex.setEnabled(val)
|
|
||||||
self.latexEqn.setEnabled(val)
|
|
||||||
self.latexMathEnv.setEnabled(val)
|
|
||||||
self.cloze.setEnabled(val)
|
|
||||||
self.htmlEdit.setEnabled(val)
|
|
||||||
self.recSound.setEnabled(val)
|
|
||||||
|
|
||||||
def disableButtons(self):
|
|
||||||
self.enableButtons(False)
|
|
||||||
|
|
||||||
def focusedEdit(self):
|
|
||||||
for (name, (field, w)) in self.fields.items():
|
|
||||||
if w.hasFocus():
|
|
||||||
return w
|
|
||||||
return None
|
|
||||||
|
|
||||||
def toggleBold(self, bool):
|
def toggleBold(self, bool):
|
||||||
self.web.eval("setFormat('bold');")
|
self.web.eval("setFormat('bold');")
|
||||||
|
@ -603,6 +525,13 @@ class Editor(object):
|
||||||
def removeFormat(self):
|
def removeFormat(self):
|
||||||
self.web.eval("setFormat('removeFormat');")
|
self.web.eval("setFormat('removeFormat');")
|
||||||
|
|
||||||
|
def onCloze(self):
|
||||||
|
self.removeFormat()
|
||||||
|
self.web.eval("cloze();")
|
||||||
|
|
||||||
|
# Foreground colour
|
||||||
|
######################################################################
|
||||||
|
|
||||||
def _updateForegroundButton(self, txtcol):
|
def _updateForegroundButton(self, txtcol):
|
||||||
self.foregroundFrame.setPalette(QPalette(QColor(txtcol)))
|
self.foregroundFrame.setPalette(QPalette(QColor(txtcol)))
|
||||||
self.foregroundFrame.setStyleSheet("* {background-color: %s}" %
|
self.foregroundFrame.setStyleSheet("* {background-color: %s}" %
|
||||||
|
@ -613,6 +542,13 @@ class Editor(object):
|
||||||
self._updateForegroundButton(recent[-1])
|
self._updateForegroundButton(recent[-1])
|
||||||
|
|
||||||
def onForeground(self):
|
def onForeground(self):
|
||||||
|
class ColourPopup(QDialog):
|
||||||
|
def __init__(self, parent):
|
||||||
|
QDialog.__init__(self, parent, Qt.FramelessWindowHint)
|
||||||
|
def event(self, evt):
|
||||||
|
if evt.type() == QEvent.WindowDeactivate:
|
||||||
|
self.close()
|
||||||
|
return QDialog.event(self, evt)
|
||||||
p = ColourPopup(self.widget)
|
p = ColourPopup(self.widget)
|
||||||
p.move(self.foregroundFrame.mapToGlobal(QPoint(0,0)))
|
p.move(self.foregroundFrame.mapToGlobal(QPoint(0,0)))
|
||||||
g = QGridLayout(p)
|
g = QGridLayout(p)
|
||||||
|
@ -700,87 +636,11 @@ class Editor(object):
|
||||||
runHook("colourChanged")
|
runHook("colourChanged")
|
||||||
self.onChooseColour(txtcol)
|
self.onChooseColour(txtcol)
|
||||||
|
|
||||||
def latexMenu(self):
|
# Audio/video/images
|
||||||
pass
|
######################################################################
|
||||||
|
|
||||||
def insertLatex(self):
|
def initMedia(self):
|
||||||
w = self.focusedEdit()
|
os.chdir(self.deck.mediaDir(create=True))
|
||||||
if w:
|
|
||||||
selected = w.textCursor().selectedText()
|
|
||||||
self.deck.mediaDir(create=True)
|
|
||||||
cur = w.textCursor()
|
|
||||||
pos = cur.position()
|
|
||||||
w.insertHtml("[latex]%s[/latex]" % selected)
|
|
||||||
cur.setPosition(pos+7)
|
|
||||||
w.setTextCursor(cur)
|
|
||||||
|
|
||||||
def insertLatexEqn(self):
|
|
||||||
w = self.focusedEdit()
|
|
||||||
if w:
|
|
||||||
selected = w.textCursor().selectedText()
|
|
||||||
self.deck.mediaDir(create=True)
|
|
||||||
cur = w.textCursor()
|
|
||||||
pos = cur.position()
|
|
||||||
w.insertHtml("[$]%s[/$]" % selected)
|
|
||||||
cur.setPosition(pos+3)
|
|
||||||
w.setTextCursor(cur)
|
|
||||||
|
|
||||||
def insertLatexMathEnv(self):
|
|
||||||
w = self.focusedEdit()
|
|
||||||
if w:
|
|
||||||
selected = w.textCursor().selectedText()
|
|
||||||
self.deck.mediaDir(create=True)
|
|
||||||
cur = w.textCursor()
|
|
||||||
pos = cur.position()
|
|
||||||
w.insertHtml("[$$]%s[/$$]" % selected)
|
|
||||||
cur.setPosition(pos+4)
|
|
||||||
w.setTextCursor(cur)
|
|
||||||
|
|
||||||
def onMore(self, toggle=None):
|
|
||||||
if toggle is None:
|
|
||||||
toggle = not self.latex.isVisible()
|
|
||||||
self.mw.config['factEditorAdvanced'] = toggle
|
|
||||||
self.latex.setShown(toggle)
|
|
||||||
self.latexEqn.setShown(toggle)
|
|
||||||
self.latexMathEnv.setShown(toggle)
|
|
||||||
self.htmlEdit.setShown(toggle)
|
|
||||||
|
|
||||||
def onCardLayout(self):
|
|
||||||
from aqt.clayout import CardLayout
|
|
||||||
if self.card:
|
|
||||||
type = 1; ord = self.card.ord
|
|
||||||
else:
|
|
||||||
type = 0; ord = 0
|
|
||||||
CardLayout(self.mw, self.fact, type=type, ord=ord, parent=self.widget)
|
|
||||||
|
|
||||||
def onCloze(self):
|
|
||||||
self.removeFormat()
|
|
||||||
self.web.eval("cloze();")
|
|
||||||
|
|
||||||
def onHtmlEdit(self):
|
|
||||||
def helpRequested():
|
|
||||||
aqt.openHelp("HtmlEditor")
|
|
||||||
w = self.focusedEdit()
|
|
||||||
if w:
|
|
||||||
self.saveFields()
|
|
||||||
d = QDialog(self.widget)
|
|
||||||
form = aqt.forms.edithtml.Ui_Dialog()
|
|
||||||
form.setupUi(d)
|
|
||||||
d.connect(form.buttonBox, SIGNAL("helpRequested()"),
|
|
||||||
helpRequested)
|
|
||||||
form.textEdit.setPlainText(self.widgets[w].value)
|
|
||||||
form.textEdit.moveCursor(QTextCursor.End)
|
|
||||||
d.exec_()
|
|
||||||
w.setHtml(unicode(form.textEdit.toPlainText()).\
|
|
||||||
replace("\n", ""))
|
|
||||||
self.saveFields()
|
|
||||||
|
|
||||||
def fieldsAreBlank(self):
|
|
||||||
for (field, widget) in self.fields.values():
|
|
||||||
#value = tidyHTML(unicode(widget.toHtml()))
|
|
||||||
if value:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def onAddPicture(self):
|
def onAddPicture(self):
|
||||||
# get this before we open the dialog
|
# get this before we open the dialog
|
||||||
|
@ -870,6 +730,46 @@ to enable recording.'''), parent=self.widget)
|
||||||
if file:
|
if file:
|
||||||
self._addSound(file, w, copy=False)
|
self._addSound(file, w, copy=False)
|
||||||
|
|
||||||
|
# LaTeX
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
def latexMenu(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def insertLatex(self):
|
||||||
|
w = self.focusedEdit()
|
||||||
|
if w:
|
||||||
|
selected = w.textCursor().selectedText()
|
||||||
|
self.deck.mediaDir(create=True)
|
||||||
|
cur = w.textCursor()
|
||||||
|
pos = cur.position()
|
||||||
|
w.insertHtml("[latex]%s[/latex]" % selected)
|
||||||
|
cur.setPosition(pos+7)
|
||||||
|
w.setTextCursor(cur)
|
||||||
|
|
||||||
|
def insertLatexEqn(self):
|
||||||
|
w = self.focusedEdit()
|
||||||
|
if w:
|
||||||
|
selected = w.textCursor().selectedText()
|
||||||
|
self.deck.mediaDir(create=True)
|
||||||
|
cur = w.textCursor()
|
||||||
|
pos = cur.position()
|
||||||
|
w.insertHtml("[$]%s[/$]" % selected)
|
||||||
|
cur.setPosition(pos+3)
|
||||||
|
w.setTextCursor(cur)
|
||||||
|
|
||||||
|
def insertLatexMathEnv(self):
|
||||||
|
w = self.focusedEdit()
|
||||||
|
if w:
|
||||||
|
selected = w.textCursor().selectedText()
|
||||||
|
self.deck.mediaDir(create=True)
|
||||||
|
cur = w.textCursor()
|
||||||
|
pos = cur.position()
|
||||||
|
w.insertHtml("[$$]%s[/$$]" % selected)
|
||||||
|
cur.setPosition(pos+4)
|
||||||
|
w.setTextCursor(cur)
|
||||||
|
|
||||||
|
|
||||||
class FactEdit(QTextEdit):
|
class FactEdit(QTextEdit):
|
||||||
|
|
||||||
def __init__(self, parent, *args):
|
def __init__(self, parent, *args):
|
||||||
|
@ -978,52 +878,18 @@ class FactEdit(QTextEdit):
|
||||||
# fixme
|
# fixme
|
||||||
if not self.mw.config['stripHTML']:
|
if not self.mw.config['stripHTML']:
|
||||||
return html
|
return html
|
||||||
html = re.sub("\n", " ", html)
|
|
||||||
html = re.sub("<br ?/?>", "\n", html)
|
|
||||||
html = re.sub("<p ?/?>", "\n\n", html)
|
|
||||||
html = re.sub('<style type="text/css">.*?</style>', "", html)
|
|
||||||
html = stripHTML(html)
|
html = stripHTML(html)
|
||||||
html = html.replace("\n", "<br>")
|
|
||||||
html = html.strip()
|
|
||||||
return html
|
return html
|
||||||
|
|
||||||
def focusOutEvent(self, evt):
|
# def focusOutEvent(self, evt):
|
||||||
QTextEdit.focusOutEvent(self, evt)
|
# if self.mw.config['preserveKeyboard'] and sys.platform.startswith("win32"):
|
||||||
self.parent.lastFocusedEdit = self
|
# self._ownLayout = GetKeyboardLayout(0)
|
||||||
self.parent.resetFormatButtons()
|
# ActivateKeyboardLayout(self._programLayout, 0)
|
||||||
self.parent.disableButtons()
|
# self.emit(SIGNAL("lostFocus"))
|
||||||
if self.mw.config['preserveKeyboard'] and sys.platform.startswith("win32"):
|
|
||||||
self._ownLayout = GetKeyboardLayout(0)
|
|
||||||
ActivateKeyboardLayout(self._programLayout, 0)
|
|
||||||
self.emit(SIGNAL("lostFocus"))
|
|
||||||
|
|
||||||
def focusInEvent(self, evt):
|
# def focusInEvent(self, evt):
|
||||||
if (self.parent.lastFocusedEdit and
|
# if self.mw.config['preserveKeyboard'] and sys.platform.startswith("win32"):
|
||||||
self.parent.lastFocusedEdit is not self):
|
# self._programLayout = GetKeyboardLayout(0)
|
||||||
# remove selection from previous widget
|
# if self._ownLayout == None:
|
||||||
try:
|
# self._ownLayout = self._programLayout
|
||||||
cur = self.parent.lastFocusedEdit.textCursor()
|
# ActivateKeyboardLayout(self._ownLayout, 0)
|
||||||
cur.clearSelection()
|
|
||||||
self.parent.lastFocusedEdit.setTextCursor(cur)
|
|
||||||
except RuntimeError:
|
|
||||||
# old widget was deleted
|
|
||||||
pass
|
|
||||||
self.lastFocusedEdit = None
|
|
||||||
QTextEdit.focusInEvent(self, evt)
|
|
||||||
self.parent.formatChanged(None)
|
|
||||||
self.parent.enableButtons()
|
|
||||||
if self.mw.config['preserveKeyboard'] and sys.platform.startswith("win32"):
|
|
||||||
self._programLayout = GetKeyboardLayout(0)
|
|
||||||
if self._ownLayout == None:
|
|
||||||
self._ownLayout = self._programLayout
|
|
||||||
ActivateKeyboardLayout(self._ownLayout, 0)
|
|
||||||
|
|
||||||
class ColourPopup(QDialog):
|
|
||||||
|
|
||||||
def __init__(self, parent):
|
|
||||||
QDialog.__init__(self, parent, Qt.FramelessWindowHint)
|
|
||||||
|
|
||||||
def event(self, evt):
|
|
||||||
if evt.type() == QEvent.WindowDeactivate:
|
|
||||||
self.close()
|
|
||||||
return QDialog.event(self, evt)
|
|
||||||
|
|
|
@ -8,21 +8,28 @@ import re, sys
|
||||||
|
|
||||||
class TagEdit(QLineEdit):
|
class TagEdit(QLineEdit):
|
||||||
|
|
||||||
def __init__(self, parent, *args):
|
# 0 = tags, 1 = groups
|
||||||
QLineEdit.__init__(self, parent, *args)
|
def __init__(self, parent, type=0):
|
||||||
|
QLineEdit.__init__(self, parent)
|
||||||
|
self.deck = None
|
||||||
self.model = QStringListModel()
|
self.model = QStringListModel()
|
||||||
|
self.type = type
|
||||||
|
if type == 0:
|
||||||
self.completer = TagCompleter(self.model, parent, self)
|
self.completer = TagCompleter(self.model, parent, self)
|
||||||
|
else:
|
||||||
|
self.completer = QCompleter(self.model, parent)
|
||||||
self.completer.setCompletionMode(QCompleter.PopupCompletion)
|
self.completer.setCompletionMode(QCompleter.PopupCompletion)
|
||||||
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
|
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
|
||||||
self.setCompleter(self.completer)
|
self.setCompleter(self.completer)
|
||||||
|
|
||||||
def setDeck(self, deck, tags="user"):
|
def setDeck(self, deck):
|
||||||
"Set the current deck, updating list of available tags."
|
"Set the current deck, updating list of available tags."
|
||||||
self.deck = deck
|
self.deck = deck
|
||||||
tags = self.deck.allTags()
|
if self.type == 0:
|
||||||
tags.sort(key=lambda x: x.lower())
|
l = self.deck.tagList()
|
||||||
self.model.setStringList(
|
else:
|
||||||
QStringList(tags))
|
l = self.deck.groups()
|
||||||
|
self.model.setStringList(QStringList(l))
|
||||||
|
|
||||||
def addTags(self, tags):
|
def addTags(self, tags):
|
||||||
l = list(set([unicode(x) for x in list(self.model.stringList())] +
|
l = list(set([unicode(x) for x in list(self.model.stringList())] +
|
||||||
|
|
|
@ -54,6 +54,7 @@ class AnkiWebView(QWebView):
|
||||||
self.connect(self, SIGNAL("linkClicked(QUrl)"), self._linkHandler)
|
self.connect(self, SIGNAL("linkClicked(QUrl)"), self._linkHandler)
|
||||||
self.connect(self, SIGNAL("loadFinished(bool)"), self._loadFinished)
|
self.connect(self, SIGNAL("loadFinished(bool)"), self._loadFinished)
|
||||||
self._curKey = None
|
self._curKey = None
|
||||||
|
self.allowDrops = False
|
||||||
def keyPressEvent(self, evt):
|
def keyPressEvent(self, evt):
|
||||||
if evt.matches(QKeySequence.Copy):
|
if evt.matches(QKeySequence.Copy):
|
||||||
self.triggerPageAction(QWebPage.Copy)
|
self.triggerPageAction(QWebPage.Copy)
|
||||||
|
@ -73,8 +74,9 @@ class AnkiWebView(QWebView):
|
||||||
QWebView.keyPressEvent(self, evt)
|
QWebView.keyPressEvent(self, evt)
|
||||||
def contextMenuEvent(self, evt):
|
def contextMenuEvent(self, evt):
|
||||||
QWebView.contextMenuEvent(self, evt)
|
QWebView.contextMenuEvent(self, evt)
|
||||||
# def dropEvent(self, evt):
|
def dropEvent(self, evt):
|
||||||
# pass
|
if self.allowDrops:
|
||||||
|
QWebView.dropEvent(self, evt)
|
||||||
def setLinkHandler(self, handler=None):
|
def setLinkHandler(self, handler=None):
|
||||||
if handler:
|
if handler:
|
||||||
self.linkHandler = handler
|
self.linkHandler = handler
|
||||||
|
|
Loading…
Reference in a new issue