mirror of
https://github.com/ankitects/anki.git
synced 2025-09-22 07:52:24 -04:00
merge audio/picture adding buttons; enable/disable editing buttons on focus change
This commit is contained in:
parent
9496b161e0
commit
3337b42565
1 changed files with 43 additions and 103 deletions
146
aqt/editor.py
146
aqt/editor.py
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
from PyQt4.QtSvg import * # fixme: obsolete?
|
|
||||||
from PyQt4.QtWebKit import QWebView
|
from PyQt4.QtWebKit import QWebView
|
||||||
import re, os, sys, tempfile, urllib2, ctypes, simplejson
|
import re, os, sys, tempfile, urllib2, ctypes, simplejson
|
||||||
from anki.utils import stripHTML
|
from anki.utils import stripHTML
|
||||||
|
@ -12,9 +11,12 @@ from anki.sound import play
|
||||||
from anki.hooks import addHook, removeHook, runHook, runFilter
|
from anki.hooks import addHook, removeHook, runHook, runFilter
|
||||||
from aqt.sound import getAudio
|
from aqt.sound import getAudio
|
||||||
from aqt.webview import AnkiWebView
|
from aqt.webview import AnkiWebView
|
||||||
from aqt.utils import shortcut, showInfo, showWarning, getBase
|
from aqt.utils import shortcut, showInfo, showWarning, getBase, getFile
|
||||||
import anki.js
|
import anki.js
|
||||||
|
|
||||||
|
pics = ("jpg", "jpeg", "png", "tif", "tiff", "gif")
|
||||||
|
audio = ("wav", "mp3", "ogg", "flac")
|
||||||
|
|
||||||
_html = """
|
_html = """
|
||||||
<html><head>%s<style>
|
<html><head>%s<style>
|
||||||
.field {
|
.field {
|
||||||
|
@ -72,6 +74,7 @@ function clearChangeTimer() {
|
||||||
function onFocus(elem) {
|
function onFocus(elem) {
|
||||||
currentField = elem;
|
currentField = elem;
|
||||||
setTimeout(foo, 1);
|
setTimeout(foo, 1);
|
||||||
|
py.run("onfocus");
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo() {
|
function foo() {
|
||||||
|
@ -90,6 +93,7 @@ function onBlur() {
|
||||||
}
|
}
|
||||||
clearChangeTimer();
|
clearChangeTimer();
|
||||||
currentField = null;
|
currentField = null;
|
||||||
|
py.run("onblur");
|
||||||
};
|
};
|
||||||
|
|
||||||
function saveField(type) {
|
function saveField(type) {
|
||||||
|
@ -254,8 +258,7 @@ class Editor(object):
|
||||||
but = b("cloze", self.onCloze, "F9", _("Cloze (F9)"), text="[...]")
|
but = b("cloze", self.onCloze, "F9", _("Cloze (F9)"), text="[...]")
|
||||||
but.setFixedWidth(24)
|
but.setFixedWidth(24)
|
||||||
# fixme: better image names
|
# fixme: better image names
|
||||||
but = b("colors", self.onAddPicture, "F3", _("Add picture (F3)"))
|
but = b("text-speak", self.onAddMedia, "F3", _("Add audio/video (F4)"))
|
||||||
but = b("text-speak", self.onAddSound, "F3", _("Add audio/video (F4)"))
|
|
||||||
but = b("media-record", self.onRecSound, "F5", _("Record audio (F5)"))
|
but = b("media-record", self.onRecSound, "F5", _("Record audio (F5)"))
|
||||||
but = b("tex", self.latexMenu, "Ctrl+t", _("LaTeX (Ctrl+t)"))
|
but = b("tex", self.latexMenu, "Ctrl+t", _("LaTeX (Ctrl+t)"))
|
||||||
# insertLatex, insertLatexEqn, insertLatexMathEnv
|
# insertLatex, insertLatexEqn, insertLatexMathEnv
|
||||||
|
@ -271,18 +274,8 @@ class Editor(object):
|
||||||
but.setLayout(hbox)
|
but.setLayout(hbox)
|
||||||
|
|
||||||
def enableButtons(self, val=True):
|
def enableButtons(self, val=True):
|
||||||
self.bold.setEnabled(val)
|
for b in self._buttons.values():
|
||||||
self.italic.setEnabled(val)
|
b.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):
|
def disableButtons(self):
|
||||||
self.enableButtons(False)
|
self.enableButtons(False)
|
||||||
|
@ -299,7 +292,11 @@ class Editor(object):
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
def bridge(self, str):
|
def bridge(self, str):
|
||||||
if str.startswith("focus") or str.startswith("key"):
|
if str.startswith("onblur"):
|
||||||
|
self.disableButtons()
|
||||||
|
elif str.startswith("onfocus"):
|
||||||
|
self.enableButtons()
|
||||||
|
elif str.startswith("focus") or str.startswith("key"):
|
||||||
print str
|
print str
|
||||||
(type, num, txt) = str.split(":", 2)
|
(type, num, txt) = str.split(":", 2)
|
||||||
self.fact._fields[int(num)] = txt
|
self.fact._fields[int(num)] = txt
|
||||||
|
@ -640,81 +637,35 @@ class Editor(object):
|
||||||
# Audio/video/images
|
# Audio/video/images
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
def initMedia(self):
|
def onAddMedia(self):
|
||||||
os.chdir(self.deck.mediaDir(create=True))
|
key = (_("Media") +
|
||||||
|
" (*.jpg *.png *.gif *.tiff *.svg *.tif *.jpeg "+
|
||||||
def onAddPicture(self):
|
"*.mp3 *.ogg *.wav *.avi *.ogv *.mpg *.mpeg *.mov *.mp4 " +
|
||||||
# get this before we open the dialog
|
|
||||||
w = self.focusedEdit()
|
|
||||||
key = (_("Images") +
|
|
||||||
" (*.jpg *.png *.gif *.tiff *.svg *.tif *.jpeg)")
|
|
||||||
file = ui.utils.getFile(self.widget, _("Add an image"), "picture", key)
|
|
||||||
if not file:
|
|
||||||
return
|
|
||||||
if file.lower().endswith(".svg"):
|
|
||||||
# convert to a png
|
|
||||||
s = QSvgRenderer(file)
|
|
||||||
i = QImage(s.defaultSize(), QImage.Format_ARGB32_Premultiplied)
|
|
||||||
p = QPainter()
|
|
||||||
p.begin(i)
|
|
||||||
s.render(p)
|
|
||||||
p.end()
|
|
||||||
(fd, name) = tempfile.mkstemp(prefix="anki", suffix=".png")
|
|
||||||
file = unicode(name, sys.getfilesystemencoding())
|
|
||||||
i.save(file)
|
|
||||||
self._addPicture(file, widget=w)
|
|
||||||
|
|
||||||
def _addPicture(self, file, widget=None):
|
|
||||||
self.initMedia()
|
|
||||||
if widget:
|
|
||||||
w = widget
|
|
||||||
else:
|
|
||||||
w = self.focusedEdit()
|
|
||||||
path = self._addMedia(file)
|
|
||||||
self.maybeDelete(path, file)
|
|
||||||
w.insertHtml('<img src="%s">' % path)
|
|
||||||
|
|
||||||
def _addMedia(self, file):
|
|
||||||
try:
|
|
||||||
return self.deck.addMedia(file)
|
|
||||||
except (IOError, OSError), e:
|
|
||||||
ui.utils.showWarning(_("Unable to add media: %s") % unicode(e),
|
|
||||||
parent=self.widget)
|
|
||||||
|
|
||||||
def onAddSound(self):
|
|
||||||
# get this before we open the dialog
|
|
||||||
w = self.focusedEdit()
|
|
||||||
key = (_("Sounds/Videos") +
|
|
||||||
" (*.mp3 *.ogg *.wav *.avi *.ogv *.mpg *.mpeg *.mov *.mp4 " +
|
|
||||||
"*.mkv *.ogx *.ogv *.oga *.flv *.swf *.flac)")
|
"*.mkv *.ogx *.ogv *.oga *.flv *.swf *.flac)")
|
||||||
file = ui.utils.getFile(self.widget, _("Add audio"), "audio", key)
|
file = getFile(self.widget, _("Add Media"), "media", key)
|
||||||
if not file:
|
if not file:
|
||||||
return
|
return
|
||||||
self._addSound(file, widget=w)
|
html = self._addMedia(file)
|
||||||
|
self.web.eval("setFormat('inserthtml', %s);" % simplejson.dumps(html))
|
||||||
|
|
||||||
def _addSound(self, file, widget=None, copy=True):
|
def _addMedia(self, path, canDelete=False):
|
||||||
self.initMedia()
|
"Add to media folder and return basename."
|
||||||
if widget:
|
# copy to media folder
|
||||||
w = widget
|
name = self.mw.deck.media.addFile(path)
|
||||||
|
# remove original?
|
||||||
|
if canDelete and self.mw.config['deleteMedia']:
|
||||||
|
if os.path.abspath(name) != os.path.abspath(path):
|
||||||
|
try:
|
||||||
|
os.unlink(old)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
# return a local html link
|
||||||
|
ext = name.split(".")[-1].lower()
|
||||||
|
if ext in pics:
|
||||||
|
return '<img src="%s">' % name
|
||||||
else:
|
else:
|
||||||
w = self.focusedEdit()
|
anki.sound.play(name)
|
||||||
if copy:
|
return '[sound:%s]' % name
|
||||||
path = self._addMedia(file)
|
|
||||||
self.maybeDelete(path, file)
|
|
||||||
else:
|
|
||||||
path = file
|
|
||||||
anki.sound.play(path)
|
|
||||||
w.insertHtml('[sound:%s]' % path)
|
|
||||||
|
|
||||||
def maybeDelete(self, new, old):
|
|
||||||
if not self.mw.config['deleteMedia']:
|
|
||||||
return
|
|
||||||
if new == os.path.basename(old):
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
os.unlink(old)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def onRecSound(self):
|
def onRecSound(self):
|
||||||
self.initMedia()
|
self.initMedia()
|
||||||
|
@ -775,8 +726,8 @@ to enable recording.'''), parent=self.widget)
|
||||||
|
|
||||||
class EditorWebView(AnkiWebView):
|
class EditorWebView(AnkiWebView):
|
||||||
|
|
||||||
pics = ("jpg", "jpeg", "png", "tif", "tiff", "gif")
|
|
||||||
audio = ("wav", "mp3", "ogg", "flac")
|
|
||||||
|
|
||||||
def __init__(self, parent, editor):
|
def __init__(self, parent, editor):
|
||||||
AnkiWebView.__init__(self, parent)
|
AnkiWebView.__init__(self, parent)
|
||||||
|
@ -890,13 +841,13 @@ class EditorWebView(AnkiWebView):
|
||||||
else:
|
else:
|
||||||
im.save(uname, None, 95)
|
im.save(uname, None, 95)
|
||||||
mime = QMimeData()
|
mime = QMimeData()
|
||||||
mime.setHtml(self._addMedia(uname))
|
mime.setHtml(self.editor._addMedia(uname))
|
||||||
return mime
|
return mime
|
||||||
|
|
||||||
def _retrieveURL(self, url):
|
def _retrieveURL(self, url):
|
||||||
# is it media?
|
# is it media?
|
||||||
ext = name.split(".")[-1].lower()
|
ext = name.split(".")[-1].lower()
|
||||||
if ext not in self.pics and ext not in self.audio:
|
if ext not in pics and ext not in audio:
|
||||||
return
|
return
|
||||||
# fetch it into a temporary folder
|
# fetch it into a temporary folder
|
||||||
try:
|
try:
|
||||||
|
@ -910,19 +861,8 @@ class EditorWebView(AnkiWebView):
|
||||||
file = open(path, "wb")
|
file = open(path, "wb")
|
||||||
file.write(filecontents)
|
file.write(filecontents)
|
||||||
file.close()
|
file.close()
|
||||||
return self._addMedia(path)
|
return self.editor._addMedia(path)
|
||||||
|
|
||||||
def _addMedia(self, path):
|
|
||||||
# copy to media folder
|
|
||||||
name = self.editor.mw.deck.media.addFile(path)
|
|
||||||
print "name was", name
|
|
||||||
# return a local html link
|
|
||||||
ext = name.split(".")[-1].lower()
|
|
||||||
if ext in self.pics:
|
|
||||||
return '<img src="%s">' % name
|
|
||||||
else:
|
|
||||||
# FIXME: should also autoplay audio
|
|
||||||
return '[sound:%s]' % name
|
|
||||||
|
|
||||||
def _tmpDir(self):
|
def _tmpDir(self):
|
||||||
if not self.__tmpDir:
|
if not self.__tmpDir:
|
||||||
|
|
Loading…
Reference in a new issue