mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
inline edit, fix images, css, scroll to bottom, status, etc
- new edit card inline mode - provide file:// url for images for webkit - look for the css file inside the anki dir - make add cards dialog more compact - launch clicked links in external window
This commit is contained in:
parent
ae776365b1
commit
518fcc3442
9 changed files with 164 additions and 68 deletions
|
@ -100,7 +100,7 @@ def run():
|
|||
ui.dialogs.registerDialogs()
|
||||
mw = ui.main.AnkiQt(app, conf, args)
|
||||
try:
|
||||
styleFile = open(opts.config + ".css")
|
||||
styleFile = open(os.path.join(opts.config, "style.css"))
|
||||
mw.setStyleSheet(styleFile.read())
|
||||
except (IOError, OSError):
|
||||
pass
|
||||
|
|
|
@ -62,13 +62,6 @@ class AddCards(QDialog):
|
|||
QDialogButtonBox.HelpRole)
|
||||
self.connect(self.helpButton, SIGNAL("clicked()"), self.helpRequested)
|
||||
|
||||
def setupStatus(self):
|
||||
"Make the status background the same colour as the frame."
|
||||
p = self.dialog.statusGroup.palette()
|
||||
c = unicode(p.color(QPalette.Window).name())
|
||||
self.dialog.status.setStyleSheet(
|
||||
"* { background: %s; color: #000000; }" % c)
|
||||
|
||||
def modelChanged(self, model):
|
||||
oldFact = self.editor.fact
|
||||
# create a new fact
|
||||
|
|
|
@ -49,7 +49,7 @@ class FactEditor(object):
|
|||
self.fields = {}
|
||||
# top level vbox
|
||||
self.fieldsBox = QVBoxLayout(self.widget)
|
||||
self.fieldsBox.setMargin(5)
|
||||
self.fieldsBox.setMargin(0)
|
||||
self.fieldsBox.setSpacing(3)
|
||||
# icons
|
||||
self.iconsBox = QHBoxLayout()
|
||||
|
@ -110,7 +110,7 @@ class FactEditor(object):
|
|||
self.foregroundFrame.setAutoFillBackground(True)
|
||||
hbox = QHBoxLayout()
|
||||
hbox.addWidget(self.foregroundFrame)
|
||||
hbox.setMargin(5)
|
||||
hbox.setMargin(0)
|
||||
self.foreground.setLayout(hbox)
|
||||
self.iconsBox.addWidget(self.foreground)
|
||||
self.foreground.setStyle(self.plastiqueStyle)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtWebKit import QWebPage
|
||||
|
||||
import os, sys, re, types, gettext, stat, traceback
|
||||
import copy, shutil, time, glob
|
||||
|
@ -54,6 +55,9 @@ class AnkiQt(QMainWindow):
|
|||
self.addView(self.bodyView)
|
||||
self.statusView = ui.status.StatusView(self)
|
||||
self.addView(self.statusView)
|
||||
self.mainWin.welcomeText.hide()
|
||||
self.mainWin.mainText.hide()
|
||||
self.setupEditor()
|
||||
self.setupButtons()
|
||||
self.setupAnchors()
|
||||
self.setupToolbar()
|
||||
|
@ -110,6 +114,7 @@ class AnkiQt(QMainWindow):
|
|||
# reset current card and load again
|
||||
self.currentCard = None
|
||||
self.lastCard = None
|
||||
self.editor.deck = self.deck
|
||||
if self.deck:
|
||||
self.mainWin.menu_Lookup.setEnabled(True)
|
||||
self.enableDeckMenuItems()
|
||||
|
@ -128,9 +133,11 @@ class AnkiQt(QMainWindow):
|
|||
self.lastState = getattr(self, "state", None)
|
||||
self.state = state
|
||||
self.updateTitleBar()
|
||||
if 'state' != 'noDeck':
|
||||
if 'state' != 'noDeck' and state != 'editCurrentFact':
|
||||
self.mainWin.welcomeText.hide()
|
||||
self.mainWin.mainText.show()
|
||||
self.mainWin.buttonWidget.show()
|
||||
self.mainWin.fieldsArea.hide()
|
||||
if state == "noDeck":
|
||||
self.mainWin.welcomeText.show()
|
||||
self.mainWin.mainText.hide()
|
||||
|
@ -183,6 +190,14 @@ class AnkiQt(QMainWindow):
|
|||
self.resetButtons()
|
||||
self.showEaseButtons()
|
||||
self.enableCardMenuItems()
|
||||
elif state == "editCurrentFact":
|
||||
self.resetButtons()
|
||||
self.showSaveEditorButton()
|
||||
self.mainWin.mainText.hide()
|
||||
self.mainWin.fieldsArea.show()
|
||||
self.editor.setFact(self.currentCard.fact)
|
||||
elif state == "saveEdit":
|
||||
return self.moveToState("auto")
|
||||
self.updateViews(state)
|
||||
|
||||
def keyPressEvent(self, evt):
|
||||
|
@ -751,12 +766,19 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
|||
self.onAddCard()
|
||||
|
||||
def setupAnchors(self):
|
||||
# welcome
|
||||
self.anchorPrefixes = {
|
||||
'welcome': self.onWelcomeAnchor,
|
||||
}
|
||||
self.connect(self.mainWin.welcomeText,
|
||||
SIGNAL("anchorClicked(QUrl)"),
|
||||
self.anchorClicked)
|
||||
# main
|
||||
self.mainWin.mainText.page().setLinkDelegationPolicy(
|
||||
QWebPage.DelegateExternalLinks)
|
||||
self.connect(self.mainWin.mainText,
|
||||
SIGNAL("linkClicked(QUrl)"),
|
||||
self.linkClicked)
|
||||
|
||||
def anchorClicked(self, url):
|
||||
# prevent the link being handled
|
||||
|
@ -769,6 +791,36 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
|||
# open in browser
|
||||
QDesktopServices.openUrl(QUrl(url))
|
||||
|
||||
def linkClicked(self, url):
|
||||
QDesktopServices.openUrl(QUrl(url))
|
||||
|
||||
# Edit current fact
|
||||
##########################################################################
|
||||
|
||||
def setupEditor(self):
|
||||
self.mainWin.fieldsArea.hide()
|
||||
self.editor = ui.facteditor.FactEditor(
|
||||
self, self.mainWin.fieldsArea, self.deck)
|
||||
self.editor.onFactValid = self.onFactValid
|
||||
self.editor.onFactInvalid = self.onFactInvalid
|
||||
|
||||
def showSaveEditorButton(self):
|
||||
if self.lastState == self.state:
|
||||
return
|
||||
self.editFactButton = QPushButton(_("Return (Esc)"))
|
||||
self.editFactButton.setFixedHeight(self.easeButtonHeight)
|
||||
self.editFactButton.setShortcut(_("Esc"))
|
||||
self.editFactButton.setDefault(False)
|
||||
self.buttonBox.addWidget(self.editFactButton)
|
||||
self.connect(self.editFactButton, SIGNAL("clicked()"),
|
||||
lambda: self.moveToState("saveEdit"))
|
||||
|
||||
def onFactValid(self, fact):
|
||||
self.editFactButton.setEnabled(True)
|
||||
|
||||
def onFactInvalid(self, fact):
|
||||
self.editFactButton.setEnabled(False)
|
||||
|
||||
# Toolbar
|
||||
##########################################################################
|
||||
|
||||
|
@ -783,6 +835,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
|||
mw.toolBar.hide()
|
||||
mw.toolBar = QToolBar(self)
|
||||
mw.toolBar.addAction(mw.actionAddcards)
|
||||
mw.toolBar.addAction(mw.actionEditCurrent)
|
||||
mw.toolBar.addAction(mw.actionEditdeck)
|
||||
mw.toolBar.addAction(mw.actionRepeatAudio)
|
||||
mw.toolBar.addAction(mw.actionMarkCard)
|
||||
|
@ -932,6 +985,9 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
|||
def onEditDeck(self):
|
||||
ui.dialogs.get("CardList", self)
|
||||
|
||||
def onEditCurrent(self):
|
||||
self.moveToState("editCurrentFact")
|
||||
|
||||
def onDeckProperties(self):
|
||||
self.deckProperties = ui.deckproperties.DeckProperties(self)
|
||||
|
||||
|
@ -1213,6 +1269,7 @@ To upgrade an old deck, download Anki 0.9.8.7."""))
|
|||
self.connect(m.actionDisplayProperties, s,self.onDisplayProperties)
|
||||
self.connect(m.actionAddcards, s, self.onAddCard)
|
||||
self.connect(m.actionEditdeck, s, self.onEditDeck)
|
||||
self.connect(m.actionEditCurrent, s, self.onEditCurrent)
|
||||
self.connect(m.actionPreferences, s, self.onPrefs)
|
||||
self.connect(m.actionLookup_es, s, self.onLookupEdictSelection)
|
||||
self.connect(m.actionLookup_esk, s, self.onLookupEdictKanjiSelection)
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtWebKit import QWebPage
|
||||
import anki, anki.utils
|
||||
from anki.sound import playFromText, stripSounds
|
||||
from anki.latex import renderLatex, stripLatex
|
||||
from anki.utils import stripHTML
|
||||
import types, time
|
||||
import types, time, re, os
|
||||
from ankiqt import ui
|
||||
|
||||
# Views - define the way a user is prompted for questions, etc
|
||||
|
@ -110,19 +109,24 @@ class View(object):
|
|||
# Question and answer
|
||||
##########################################################################
|
||||
|
||||
def munge(self, txt):
|
||||
txt = renderLatex(self.main.deck, txt)
|
||||
txt = stripSounds(txt)
|
||||
txt = re.sub(
|
||||
'img src="(.*?)"', 'img src="file://%s/\\1"' % os.getcwd(), txt)
|
||||
return txt
|
||||
|
||||
def drawQuestion(self, nosound=False):
|
||||
"Show the question."
|
||||
q = self.main.currentCard.htmlQuestion()
|
||||
q = renderLatex(self.main.deck, q)
|
||||
self.write(stripSounds(q))
|
||||
self.write(self.munge(q))
|
||||
if self.state != self.oldState and not nosound:
|
||||
playFromText(q)
|
||||
|
||||
def drawAnswer(self):
|
||||
"Show the answer."
|
||||
a = self.main.currentCard.htmlAnswer()
|
||||
a = renderLatex(self.main.deck, a)
|
||||
self.write('<span id=answer />' + stripSounds(a))
|
||||
self.write('<span id=answer />' + self.munge(a))
|
||||
if self.state != self.oldState:
|
||||
playFromText(a)
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>505</width>
|
||||
<height>367</height>
|
||||
<width>509</width>
|
||||
<height>381</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
|
@ -21,15 +21,25 @@
|
|||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<property name="horizontalSpacing" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="verticalSpacing" >
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QWidget" native="1" name="modelArea" />
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="Line" name="line" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -41,53 +51,48 @@
|
|||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>5</verstretch>
|
||||
<verstretch>10</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="autoFillBackground" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<string>Fields</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="flat" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="statusGroup" >
|
||||
<widget class="QTextEdit" name="status" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<string>Status</string>
|
||||
<property name="autoFillBackground" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy" >
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy" >
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="html" >
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Arial'; font-size:8pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="status" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy" >
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy" >
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>532</width>
|
||||
<height>442</height>
|
||||
<width>454</width>
|
||||
<height>504</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
|
@ -27,8 +27,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>69</y>
|
||||
<width>532</width>
|
||||
<height>353</height>
|
||||
<width>454</width>
|
||||
<height>415</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
|
@ -129,6 +129,28 @@
|
|||
<property name="margin" >
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="fieldsArea" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
|
||||
<horstretch>7</horstretch>
|
||||
<verstretch>2</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="autoFillBackground" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="flat" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checkable" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="welcomeText" >
|
||||
<property name="focusPolicy" >
|
||||
|
@ -351,7 +373,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>532</width>
|
||||
<width>454</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -376,6 +398,7 @@
|
|||
<addaction name="actionUndoAnswer" />
|
||||
<addaction name="separator" />
|
||||
<addaction name="actionAddcards" />
|
||||
<addaction name="actionEditCurrent" />
|
||||
<addaction name="actionEditdeck" />
|
||||
<addaction name="separator" />
|
||||
<addaction name="actionActiveTags" />
|
||||
|
@ -487,8 +510,8 @@
|
|||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>422</y>
|
||||
<width>532</width>
|
||||
<y>484</y>
|
||||
<width>454</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -501,7 +524,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>23</y>
|
||||
<width>532</width>
|
||||
<width>454</width>
|
||||
<height>46</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -526,6 +549,7 @@
|
|||
<addaction name="actionSyncdeck" />
|
||||
<addaction name="separator" />
|
||||
<addaction name="actionAddcards" />
|
||||
<addaction name="actionEditCurrent" />
|
||||
<addaction name="actionEditdeck" />
|
||||
<addaction name="actionDisplayProperties" />
|
||||
<addaction name="separator" />
|
||||
|
@ -617,7 +641,7 @@
|
|||
<string>&Add Items..</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string>Ctrl+A</string>
|
||||
<string>Alt+Shift+A</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEditdeck" >
|
||||
|
@ -626,10 +650,10 @@
|
|||
<normaloff>:/icons/view_text.png</normaloff>:/icons/view_text.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>&Edit Items..</string>
|
||||
<string>Ed&it All..</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string>Ctrl+E</string>
|
||||
<string>Alt+Shift+I</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreferences" >
|
||||
|
@ -999,6 +1023,18 @@
|
|||
<string>&Get More Decks..</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEditCurrent" >
|
||||
<property name="icon" >
|
||||
<iconset resource="../icons.qrc" >
|
||||
<normaloff>:/icons/edit-rename.png</normaloff>:/icons/edit-rename.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>&Edit Current..</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string>Alt+Shift+E</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>icons/edit-rename.png</file>
|
||||
<file>icons/kblogger.png</file>
|
||||
<file>icons/chronometer.png</file>
|
||||
<file>icons/Anki_Card.png</file>
|
||||
|
|
BIN
icons/edit-rename.png
Normal file
BIN
icons/edit-rename.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 496 B |
Loading…
Reference in a new issue