mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
ankiqt support for drag-and-drop changes of deck hierarchy in deckbrowser
This commit is contained in:
parent
7678ddcf45
commit
fd23b4f6b2
1 changed files with 55 additions and 6 deletions
|
@ -5,6 +5,7 @@
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.utils import askUser, getOnlyText, openLink, showWarning
|
from aqt.utils import askUser, getOnlyText, openLink, showWarning
|
||||||
from anki.utils import isMac
|
from anki.utils import isMac
|
||||||
|
from anki.errors import DeckRenameError
|
||||||
import aqt
|
import aqt
|
||||||
|
|
||||||
class DeckBrowser(object):
|
class DeckBrowser(object):
|
||||||
|
@ -36,6 +37,9 @@ class DeckBrowser(object):
|
||||||
self._onShared()
|
self._onShared()
|
||||||
elif cmd == "import":
|
elif cmd == "import":
|
||||||
self.mw.onImport()
|
self.mw.onImport()
|
||||||
|
elif cmd == "drag":
|
||||||
|
draggedDeckDid, ontoDeckDid = arg.split(',')
|
||||||
|
self._dragDeckOnto(draggedDeckDid, ontoDeckDid)
|
||||||
|
|
||||||
def _selDeck(self, did):
|
def _selDeck(self, did):
|
||||||
self.mw.col.decks.select(did)
|
self.mw.col.decks.select(did)
|
||||||
|
@ -48,7 +52,7 @@ class DeckBrowser(object):
|
||||||
a.deck { color: #000; text-decoration: none; font-size: 12px; }
|
a.deck { color: #000; text-decoration: none; font-size: 12px; }
|
||||||
a.deck:hover { text-decoration: underline; }
|
a.deck:hover { text-decoration: underline; }
|
||||||
td.opts { white-space: nowrap; }
|
td.opts { white-space: nowrap; }
|
||||||
td.deck { width: 90% }
|
.drag-hover { background-color: #448; }
|
||||||
.extra { font-size: 90%; }
|
.extra { font-size: 90%; }
|
||||||
body { margin: 1em; -webkit-user-select: none; }
|
body { margin: 1em; -webkit-user-select: none; }
|
||||||
"""
|
"""
|
||||||
|
@ -59,11 +63,42 @@ body { margin: 1em; -webkit-user-select: none; }
|
||||||
%(tree)s
|
%(tree)s
|
||||||
</table>
|
</table>
|
||||||
</center>
|
</center>
|
||||||
|
<script>
|
||||||
|
$( init );
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
$("tr.deck").draggable({
|
||||||
|
scroll: false,
|
||||||
|
|
||||||
|
// can't use "helper: 'clone'" because of a bug in jQuery 1.5
|
||||||
|
helper: function (event) {
|
||||||
|
return $(this).clone(false);
|
||||||
|
},
|
||||||
|
opacity: 0.7
|
||||||
|
});
|
||||||
|
$("tr.deck").droppable({
|
||||||
|
drop: handleDropEvent,
|
||||||
|
hoverClass: 'drag-hover',
|
||||||
|
});
|
||||||
|
$("tr.bottom-row").droppable({
|
||||||
|
drop: handleDropEvent,
|
||||||
|
hoverClass: 'drag-hover',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDropEvent(event, ui) {
|
||||||
|
var draggedDeckId = ui.draggable.attr('id');
|
||||||
|
var ontoDeckId = $(this).attr('id');
|
||||||
|
|
||||||
|
py.link("drag:" + draggedDeckId + "," + ontoDeckId);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _renderPage(self):
|
def _renderPage(self):
|
||||||
css = self.mw.sharedCSS + self._css
|
css = self.mw.sharedCSS + self._css
|
||||||
tree = self._renderDeckTree(self.mw.col.sched.deckDueTree())
|
tree = self._renderDeckTree(self.mw.col.sched.deckDueTree()) \
|
||||||
|
+ self._bogusBottomRowForDraggingDeckToTopLevel()
|
||||||
self.web.stdHtml(self._body%dict(
|
self.web.stdHtml(self._body%dict(
|
||||||
title=_("Decks"),
|
title=_("Decks"),
|
||||||
tree=tree), css=css)
|
tree=tree), css=css)
|
||||||
|
@ -82,7 +117,7 @@ body { margin: 1em; -webkit-user-select: none; }
|
||||||
def indent():
|
def indent():
|
||||||
return " "*3*depth
|
return " "*3*depth
|
||||||
# due image
|
# due image
|
||||||
buf = "<tr><td colspan=5>" + indent() + self._dueImg(due, new)
|
buf = "<tr class='deck' id='%d'><td colspan=5>"%did + indent() + self._dueImg(due, new)
|
||||||
# deck link
|
# deck link
|
||||||
buf += " <a class=deck href='open:%d'>%s</a></td>"% (did, name)
|
buf += " <a class=deck href='open:%d'>%s</a></td>"% (did, name)
|
||||||
# options
|
# options
|
||||||
|
@ -92,6 +127,9 @@ body { margin: 1em; -webkit-user-select: none; }
|
||||||
buf += self._renderDeckTree(children, depth+1)
|
buf += self._renderDeckTree(children, depth+1)
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
def _bogusBottomRowForDraggingDeckToTopLevel(self):
|
||||||
|
return "<tr class='bottom-row'><td colspan='6'> </td></tr>"
|
||||||
|
|
||||||
def _dueImg(self, due, new):
|
def _dueImg(self, due, new):
|
||||||
if due:
|
if due:
|
||||||
i = "clock-icon"
|
i = "clock-icon"
|
||||||
|
@ -120,9 +158,20 @@ body { margin: 1em; -webkit-user-select: none; }
|
||||||
newName = newName.replace("'", "").replace('"', "")
|
newName = newName.replace("'", "").replace('"', "")
|
||||||
if not newName or newName == oldName:
|
if not newName or newName == oldName:
|
||||||
return
|
return
|
||||||
if deck in self.mw.col.decks.allNames():
|
|
||||||
return showWarning(_("That deck already exists."))
|
try:
|
||||||
self.mw.col.decks.rename(deck, newName)
|
self.mw.col.decks.rename(deck, newName)
|
||||||
|
except DeckRenameError, e:
|
||||||
|
return showWarning(e.description)
|
||||||
|
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def _dragDeckOnto(self, draggedDeckDid, ontoDeckDid):
|
||||||
|
try:
|
||||||
|
self.mw.col.decks.renameForDragAndDrop(draggedDeckDid, ontoDeckDid)
|
||||||
|
except DeckRenameError, e:
|
||||||
|
return showWarning(e.description)
|
||||||
|
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
def _delete(self, did):
|
def _delete(self, did):
|
||||||
|
|
Loading…
Reference in a new issue