many changes - see detailed log below

- don't use psyco
- bump version number
- autosave more often
- no last card period/text by default
- 3 buttons not 5
- default to tray off
- don't show only current card anymore
- simple toolbar
- support for sources
- don't force size of main window
- new button definitions
- remove vertical answer button support
- ditch 'how well did you remember'
- open online deck no longer hidden in new deck dialog
- default to simple model, no more 'what do you want to learn?'
- prompt user for sync username/password if not set
- simplify dialogs, add help buttons, move documentation to wiki
- don't make the timer change colors - distracting, and punishes
  people who practice writing
- remove 'empty deck' message, allow people to add cards from main screen
- remove 'welcome to anki' message. make the initial user
  experience nicer
This commit is contained in:
Damien Elmes 2008-10-10 16:54:30 +09:00
parent e751089c24
commit 8739e164ac
16 changed files with 401 additions and 290 deletions

View file

@ -6,10 +6,10 @@ from PyQt4.QtCore import *
from PyQt4.QtGui import * from PyQt4.QtGui import *
appName="Anki" appName="Anki"
appVersion="0.9.8.1" appVersion="0.9.8.2"
appWebsite="http://ichi2.net/anki/download/" appWebsite="http://ichi2.net/anki/download/"
appWiki="http://ichi2.net/anki/wiki/" appWiki="http://ichi2.net/anki/wiki/"
appHelpSite="http://ichi2.net/anki/wiki/Documentation" appHelpSite="http://ichi2.net/anki/wiki/AnkiWiki"
appIssueTracker="http://code.google.com/p/anki/issues/list" appIssueTracker="http://code.google.com/p/anki/issues/list"
appForum="http://groups.google.com/group/ankisrs/topics" appForum="http://groups.google.com/group/ankisrs/topics"
modDir=os.path.dirname(os.path.abspath(__file__)) modDir=os.path.dirname(os.path.abspath(__file__))
@ -87,14 +87,14 @@ def run():
except (IOError, OSError): except (IOError, OSError):
pass pass
import platform # import platform
if (platform.processor() != "powerpc" and # if (platform.processor() != "powerpc" and
platform.architecture()[0] == "32bit"): # platform.architecture()[0] == "32bit"):
try: # try:
import psyco # import psyco
psyco.profile() # psyco.profile()
except ImportError: # except ImportError:
print "Installing python-psyco is strongly recommended." # print "Installing python-psyco is strongly recommended."
app.exec_() app.exec_()

View file

@ -38,22 +38,22 @@ class Config(dict):
'showToolbar': True, 'showToolbar': True,
'recentDeckPaths': [], 'recentDeckPaths': [],
'saveAfterAnswer': True, 'saveAfterAnswer': True,
'saveAfterAnswerNum': 30, 'saveAfterAnswerNum': 10,
'saveAfterAdding': True, 'saveAfterAdding': True,
'saveAfterAddingNum': 10, 'saveAfterAddingNum': 3,
'saveOnClose': True, 'saveOnClose': True,
'mainWindowSize': QSize(550, 625), 'mainWindowSize': QSize(450, 400),
'mainWindowPos': QPoint(100, 100), 'mainWindowPos': QPoint(100, 100),
'easeButtonStyle': 'standard',
'easeButtonHeight': 'standard', 'easeButtonHeight': 'standard',
'suppressUpdate': False, 'suppressUpdate': False,
'suppressEstimates': False, 'suppressEstimates': False,
'suppressLastCardInterval': False, 'showLastCardInterval': False,
'suppressLastCardContent': False, 'showLastCardContent': False,
'showTray': False, 'showTrayIcon': False,
'showTimer': True, 'showTimer': True,
'editCurrentOnly': True,
'showSuspendedCards': True, 'showSuspendedCards': True,
'show3AnswerButtons': True,
'simpleToolbar': True,
} }
for (k,v) in fields.items(): for (k,v) in fields.items():
if not self.has_key(k): if not self.has_key(k):

View file

@ -260,21 +260,15 @@ class EditDeck(QDialog):
def selectLastCard(self): def selectLastCard(self):
"Show the row corresponding to the current card." "Show the row corresponding to the current card."
if self.parent.config['editCurrentOnly']:
if self.parent.currentCard:
self.dialog.filterEdit.setText("<current>")
self.dialog.filterEdit.selectAll()
self.updateSearch() self.updateSearch()
if not self.parent.config['editCurrentOnly']: if self.parent.currentCard:
if self.parent.currentCard: currentCardIndex = self.findCardInDeckModel(
currentCardIndex = self.findCardInDeckModel( self.model, self.parent.currentCard )
self.model, self.parent.currentCard ) if currentCardIndex >= 0:
if currentCardIndex >= 0: self.dialog.tableView.selectRow( currentCardIndex )
self.dialog.tableView.selectRow( currentCardIndex ) self.dialog.tableView.scrollTo(
self.dialog.tableView.scrollTo( self.model.index(currentCardIndex,0),
self.model.index(currentCardIndex,0), self.dialog.tableView.PositionAtTop )
self.dialog.tableView.PositionAtTop )
def setupFilter(self): def setupFilter(self):
self.filterTimer = None self.filterTimer = None

View file

@ -3,12 +3,13 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import sys, re import sys, re, time
import ankiqt.forms import ankiqt.forms
import anki import anki
from ankiqt import ui from ankiqt import ui
from anki.utils import parseTags from anki.utils import parseTags
from anki.deck import newCardOrderLabels, newCardSchedulingLabels from anki.deck import newCardOrderLabels, newCardSchedulingLabels
from anki.utils import hexifyID, dehexifyID
tabs = ("Synchronization", tabs = ("Synchronization",
"Scheduling", "Scheduling",
@ -34,6 +35,9 @@ class DeckProperties(QDialog):
self.connect(self.dialog.modelsEdit, SIGNAL("clicked()"), self.onEdit) self.connect(self.dialog.modelsEdit, SIGNAL("clicked()"), self.onEdit)
self.connect(self.dialog.modelsDelete, SIGNAL("clicked()"), self.onDelete) self.connect(self.dialog.modelsDelete, SIGNAL("clicked()"), self.onDelete)
self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"), self.helpRequested) self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"), self.helpRequested)
self.connect(self.dialog.addSource, SIGNAL("clicked()"), self.onAddSource)
self.connect(self.dialog.deleteSource, SIGNAL("clicked()"), self.onDeleteSource)
self.show() self.show()
def readData(self): def readData(self):
@ -67,9 +71,37 @@ class DeckProperties(QDialog):
self.dialog.newCardsPerDay.setText(unicode(self.d.newCardsPerDay)) self.dialog.newCardsPerDay.setText(unicode(self.d.newCardsPerDay))
self.dialog.newCardOrder.setCurrentIndex(self.d.newCardOrder) self.dialog.newCardOrder.setCurrentIndex(self.d.newCardOrder)
self.dialog.newCardScheduling.setCurrentIndex(self.d.newCardSpacing) self.dialog.newCardScheduling.setCurrentIndex(self.d.newCardSpacing)
# sources
self.sources = self.d.s.all("select id, name from sources")
self.sourcesToRemove = []
self.drawSourcesTable()
# models # models
self.updateModelsList() self.updateModelsList()
def drawSourcesTable(self):
self.dialog.sourcesTable.clear()
self.dialog.sourcesTable.setRowCount(len(self.sources))
self.dialog.sourcesTable.setColumnCount(2)
self.dialog.sourcesTable.setHorizontalHeaderLabels(
QStringList([_("ID"),
_("Name")]))
self.dialog.sourcesTable.horizontalHeader().setResizeMode(
QHeaderView.Stretch)
self.dialog.sourcesTable.verticalHeader().hide()
self.dialog.sourcesTable.setSelectionBehavior(
QAbstractItemView.SelectRows)
self.dialog.sourcesTable.setSelectionMode(
QAbstractItemView.SingleSelection)
self.sourceItems = []
n = 0
for (id, name) in self.sources:
a = QTableWidgetItem(hexifyID(id))
b = QTableWidgetItem(name)
self.sourceItems.append([a, b])
self.dialog.sourcesTable.setItem(n, 0, a)
self.dialog.sourcesTable.setItem(n, 1, b)
n += 1
def updateModelsList(self): def updateModelsList(self):
self.dialog.modelsList.clear() self.dialog.modelsList.clear()
self.models = [] self.models = []
@ -137,6 +169,26 @@ class DeckProperties(QDialog):
"DeckProperties#" + "DeckProperties#" +
tabs[idx])) tabs[idx]))
def onAddSource(self):
(s, ret) = QInputDialog.getText(self, _("Anki"),
_("Source ID:"))
if not s:
return
rc = self.dialog.sourcesTable.rowCount()
self.dialog.sourcesTable.insertRow(rc)
a = QTableWidgetItem(s)
b = QTableWidgetItem("")
self.dialog.sourcesTable.setItem(rc, 0, a)
self.dialog.sourcesTable.setItem(rc, 1, b)
def onDeleteSource(self):
r = self.dialog.sourcesTable.currentRow()
if r == -1:
return
self.dialog.sourcesTable.removeRow(r)
id = self.sources[r][0]
self.sourcesToRemove.append(id)
def reject(self): def reject(self):
# description # description
self.updateField(self.d, 'description', self.updateField(self.d, 'description',
@ -194,6 +246,36 @@ class DeckProperties(QDialog):
self.dialog.newCardOrder.currentIndex()) self.dialog.newCardOrder.currentIndex())
self.updateField(self.d, "newCardSpacing", self.updateField(self.d, "newCardSpacing",
self.dialog.newCardScheduling.currentIndex()) self.dialog.newCardScheduling.currentIndex())
# sources
d = {}
d.update(self.sources)
for n in range(self.dialog.sourcesTable.rowCount()):
try:
id = dehexifyID(str(self.dialog.sourcesTable.item(n, 0).text()))
except (ValueError,OverflowError):
continue
name = unicode(self.dialog.sourcesTable.item(n, 1).text())
if id in d:
if d[id] == name:
del d[id]
continue
# name changed
self.d.s.statement(
"update sources set name = :n where id = :id",
id=id, n=name)
else:
self.d.s.statement("""
insert into sources values
(:id, :n, :t, 0, 0)""", id=id, n=name, t=time.time())
self.d.setModified()
try:
del d[id]
except KeyError:
pass
for id in self.sourcesToRemove + d.keys():
self.d.s.statement("delete from sources where id = :id",
id=id)
self.d.setModified()
# mark deck dirty and close # mark deck dirty and close
if self.origMod != self.d.modified: if self.origMod != self.d.modified:
self.parent.reset() self.parent.reset()

View file

@ -12,7 +12,7 @@ import ankiqt.forms
class HelpArea(object): class HelpArea(object):
helpAreaWidth = 300 helpAreaWidth = 300
minAppWidth = 500 minAppWidth = 400
def __init__(self, helpFrame, config, mainWindow=None, focus=None): def __init__(self, helpFrame, config, mainWindow=None, focus=None):
self.helpFrame = helpFrame self.helpFrame = helpFrame
@ -27,16 +27,11 @@ class HelpArea(object):
self.anchorClicked) self.anchorClicked)
self.hide() self.hide()
def getMinAppWidth(self):
if self.config['easeButtonStyle'] == 'compact':
return self.minAppWidth - 150
return self.minAppWidth
def show(self): def show(self):
"Show the help area." "Show the help area."
if self.mainWindow: if self.mainWindow:
self.mainWindow.setMinimumWidth( self.mainWindow.setMinimumWidth(
self.getMinAppWidth()+self.helpAreaWidth) self.minAppWidth+self.helpAreaWidth)
self.helpFrame.show() self.helpFrame.show()
self.widget.show() self.widget.show()
@ -45,14 +40,6 @@ class HelpArea(object):
self.helpFrame.hide() self.helpFrame.hide()
self.widget.hide() self.widget.hide()
if self.mainWindow: if self.mainWindow:
self.mainWindow.setMinimumWidth(self.getMinAppWidth())
# force resize
g = self.mainWindow.geometry()
if g.width() < self.getMinAppWidth():
self.mainWindow.setGeometry(QRect(g.left(),
g.top(),
self.getMinAppWidth(),
g.height()))
self.mainWindow.runHook("helpChanged") self.mainWindow.runHook("helpChanged")
def showKey(self, key, noFlush=False, dict=False): def showKey(self, key, noFlush=False, dict=False):

View file

@ -33,6 +33,7 @@ class AnkiQt(QMainWindow):
self.app = app self.app = app
self.config = config self.config = config
self.deck = None self.deck = None
self.state = "initial"
self.views = [] self.views = []
self.setLang() self.setLang()
self.setupFonts() self.setupFonts()
@ -55,9 +56,7 @@ class AnkiQt(QMainWindow):
self.addView(self.statusView) self.addView(self.statusView)
self.setupButtons() self.setupButtons()
self.setupAnchors() self.setupAnchors()
if not self.config['showToolbar']: self.setupToolbar()
self.removeToolBar(self.mainWin.toolBar)
self.mainWin.toolBar.hide()
self.show() self.show()
if sys.platform.startswith("darwin"): if sys.platform.startswith("darwin"):
self.setUnifiedTitleAndToolBarOnMac(True) self.setUnifiedTitleAndToolBarOnMac(True)
@ -74,7 +73,7 @@ class AnkiQt(QMainWindow):
self.runHook('init') self.runHook('init')
except: except:
print _("Error running initHook. Broken plugin?") print _("Error running initHook. Broken plugin?")
print traceback.print_exc() traceback.print_exc()
# check for updates # check for updates
self.setupAutoUpdate() self.setupAutoUpdate()
@ -331,76 +330,50 @@ class AnkiQt(QMainWindow):
for i in range(5): for i in range(5):
s=self.deck.nextIntervalStr(self.currentCard, i) s=self.deck.nextIntervalStr(self.currentCard, i)
nextInts["ease%d" % i] = s nextInts["ease%d" % i] = s
text = (
(_("Completely forgot"), ""),
(_("Made a mistake"), ""),
(_("Difficult"),
_("Next in <b>%(ease2)s</b>")),
(_("About right"),
_("Next in <b>%(ease3)s</b>")),
(_("Easy"),
_("Next in <b>%(ease4)s</b>")))
# button grid # button grid
grid = QGridLayout() grid = QGridLayout()
grid.setSpacing(3) grid.setSpacing(3)
if self.config['easeButtonStyle'] == 'standard': if self.config['show3AnswerButtons']:
button3 = self.showStandardEaseButtons(grid, nextInts, text) rng = (1, 4)
else: else:
button3 = self.showCompactEaseButtons(grid, nextInts) rng = (0, 5)
self.buttonBox.addLayout(grid) button3 = self.showCompactEaseButtons(grid, nextInts, rng)
hbox = QHBoxLayout()
hbox.addStretch()
hbox.addLayout(grid)
hbox.addStretch()
self.buttonBox.addLayout(hbox)
button3.setFocus() button3.setFocus()
def showStandardEaseButtons(self, grid, nextInts, text): def showCompactEaseButtons(self, grid, nextInts, rng):
# show 'how well?' message
hbox = QHBoxLayout()
hbox.addItem(self.getSpacer(QSizePolicy.Expanding))
label = QLabel(self.withInterfaceFont(
_("<b>How well did you remember?</b>")))
hbox.addWidget(label)
hbox.addItem(self.getSpacer(QSizePolicy.Expanding))
self.buttonBox.addLayout(hbox)
# populate buttons
button3 = None
for i in range(5):
button = QPushButton(str(i))
button.setFixedWidth(100)
button.setFixedHeight(self.easeButtonHeight)
if i == 3:
button3 = button
grid.addItem(self.getSpacer(QSizePolicy.Expanding), i, 0)
grid.addWidget(button, i, 1)
grid.addItem(self.getSpacer(), i, 2)
grid.addWidget(QLabel(self.withInterfaceFont(text[i][0])), i, 3)
grid.addItem(self.getSpacer(), i, 4)
if not self.config['suppressEstimates']:
grid.addWidget(QLabel(self.withInterfaceFont(
text[i][1] % nextInts)), i, 5)
grid.addItem(self.getSpacer(QSizePolicy.Expanding), i, 6)
self.connect(button, SIGNAL("clicked()"),
lambda i=i: self.cardAnswered(i))
return button3
def showCompactEaseButtons(self, grid, nextInts):
text = ( text = (
(_("<b>%(ease0)s</b>")), (_("<b>%(ease0)s</b>"),
(_("<b>%(ease1)s</b>")), _("<b>Reset.</b><br>You've completely forgotten.")),
(_("<b>%(ease2)s</b>")), (_("<b>%(ease1)s</b>"),
(_("<b>%(ease3)s</b>")), _("<b>Too difficult.</b><br>Show this card again soon.")),
(_("<b>%(ease4)s</b>"))) (_("<b>%(ease2)s</b>"),
_("<b>Challenging.</b><br>Wait a little longer next time.")),
(_("<b>%(ease3)s</b>"),
_("<b>Comfortable.</b><br>Wait longer next time.")),
(_("<b>%(ease4)s</b>"),
_("<b>Too easy.</b><br>Wait a lot longer next time.")))
button3 = None button3 = None
for i in range(5): for i in range(*rng):
if not self.config['suppressEstimates']:
label = QLabel(self.withInterfaceFont(text[i][0] % nextInts))
label.setAlignment(Qt.AlignHCenter)
grid.addWidget(label, 0, (i*2)+1)
button = QPushButton(str(i)) button = QPushButton(str(i))
button.setFixedHeight(self.easeButtonHeight) button.setFixedHeight(self.easeButtonHeight)
if rng[0] == 1:
button.setFixedWidth(120)
button.setToolTip(text[i][1])
self.connect(button, SIGNAL("clicked()"),
lambda i=i: self.cardAnswered(i))
#button.setFixedWidth(70) #button.setFixedWidth(70)
if i == 3: if i == 3:
button3 = button button3 = button
grid.addWidget(button, 0, (i*2)+1) grid.addWidget(button, 1, (i*2)+1)
if not self.config['suppressEstimates']:
label = QLabel(self.withInterfaceFont(text[i] % nextInts))
label.setAlignment(Qt.AlignHCenter)
grid.addWidget(label, 1, (i*2)+1)
self.connect(button, SIGNAL("clicked()"),
lambda i=i: self.cardAnswered(i))
return button3 return button3
def withInterfaceFont(self, text): def withInterfaceFont(self, text):
@ -508,10 +481,8 @@ class AnkiQt(QMainWindow):
f = unicode(args[0], sys.getfilesystemencoding()) f = unicode(args[0], sys.getfilesystemencoding())
return self.loadDeck(f) return self.loadDeck(f)
except: except:
sys.stderr.write("Error loading last deck.\n") sys.stderr.write("Error loading deck path.\n")
traceback.print_exc() traceback.print_exc()
self.deck = None
return self.moveToState("initial")
# try recent deck paths # try recent deck paths
for path in self.config['recentDeckPaths']: for path in self.config['recentDeckPaths']:
try: try:
@ -523,9 +494,7 @@ class AnkiQt(QMainWindow):
except: except:
sys.stderr.write("Error loading last deck.\n") sys.stderr.write("Error loading last deck.\n")
traceback.print_exc() traceback.print_exc()
self.deck = None self.onNew()
return self.moveToState("initial")
return self.moveToState("initial")
def getDefaultDir(self, save=False): def getDefaultDir(self, save=False):
"Try and get default dir from most recently opened file." "Try and get default dir from most recently opened file."
@ -650,19 +619,13 @@ class AnkiQt(QMainWindow):
self.saveDeck() self.saveDeck()
self.moveToState("initial") self.moveToState("initial")
def onOpenOnline(self): def ensureSyncParams(self):
if not self.saveAndClose(exit=True): return
self.deck = DeckStorage.Deck()
# ensure all changes come to us
self.deck.syncName = None
self.deck.modified = 0
self.deck.lastLoaded = self.deck.modified
if not self.config['syncUsername'] or not self.config['syncPassword']: if not self.config['syncUsername'] or not self.config['syncPassword']:
d = QDialog(self) d = QDialog(self)
vbox = QVBoxLayout() vbox = QVBoxLayout()
l = QLabel(_( l = QLabel(_(
'<h1>Open Online Deck</h1>' '<h1>Online Account</h1>'
'To load a deck from your free <a href="http://anki.ichi2.net/">online account</a>,<br>' 'To use your free <a href="http://anki.ichi2.net/">online account</a>,<br>'
"please enter your details below.<br>")) "please enter your details below.<br>"))
l.setOpenExternalLinks(True) l.setOpenExternalLinks(True)
vbox.addWidget(l) vbox.addWidget(l)
@ -684,6 +647,15 @@ class AnkiQt(QMainWindow):
d.exec_() d.exec_()
self.config['syncUsername'] = unicode(user.text()) self.config['syncUsername'] = unicode(user.text())
self.config['syncPassword'] = unicode(passwd.text()) self.config['syncPassword'] = unicode(passwd.text())
def onOpenOnline(self):
self.ensureSyncParams()
if not self.saveAndClose(exit=True): return
self.deck = DeckStorage.Deck()
# ensure all changes come to us
self.deck.syncName = None
self.deck.modified = 0
self.deck.lastLoaded = self.deck.modified
if self.config['syncUsername'] and self.config['syncPassword']: if self.config['syncUsername'] and self.config['syncPassword']:
if self.syncDeck(onlyMerge=True): if self.syncDeck(onlyMerge=True):
return return
@ -790,6 +762,12 @@ class AnkiQt(QMainWindow):
self.onOpenSamples() self.onOpenSamples()
elif str == "open": elif str == "open":
self.onOpen() self.onOpen()
elif str == "openrem":
self.onOpenOnline()
if str == "addfacts":
if not self.deck:
self.onNew()
self.onAddCard()
def setupAnchors(self): def setupAnchors(self):
self.anchorPrefixes = { self.anchorPrefixes = {
@ -810,6 +788,26 @@ class AnkiQt(QMainWindow):
# open in browser # open in browser
QDesktopServices.openUrl(QUrl(url)) QDesktopServices.openUrl(QUrl(url))
# Toolbar
##########################################################################
def setupToolbar(self):
if not self.config['showToolbar']:
self.removeToolBar(self.mainWin.toolBar)
self.mainWin.toolBar.hide()
if self.config['simpleToolbar']:
mw = self.mainWin
self.removeToolBar(mw.toolBar)
self.mainWin.toolBar.hide()
mw.toolBar = QToolBar(self)
mw.toolBar.addAction(mw.actionAddcards)
mw.toolBar.addAction(mw.actionEditdeck)
mw.toolBar.addAction(mw.actionRepeatAudio)
mw.toolBar.addAction(mw.actionMarkCard)
mw.toolBar.addAction(mw.actionGraphs)
mw.toolBar.addAction(mw.actionDisplayProperties)
self.addToolBar(Qt.TopToolBarArea, mw.toolBar)
# Tools - looking up words in the dictionary # Tools - looking up words in the dictionary
########################################################################## ##########################################################################
@ -1017,6 +1015,7 @@ class AnkiQt(QMainWindow):
reload=True, checkSources=True): reload=True, checkSources=True):
"Synchronise a deck with the server." "Synchronise a deck with the server."
# vet input # vet input
self.ensureSyncParams()
u=self.config['syncUsername'] u=self.config['syncUsername']
p=self.config['syncPassword'] p=self.config['syncPassword']
if not u or not p: if not u or not p:
@ -1138,46 +1137,48 @@ class AnkiQt(QMainWindow):
) )
def connectMenuActions(self): def connectMenuActions(self):
self.connect(self.mainWin.actionNew, SIGNAL("triggered()"), self.onNew) m = self.mainWin
self.connect(self.mainWin.actionOpenOnline, SIGNAL("triggered()"), self.onOpenOnline) s = SIGNAL("triggered()")
self.connect(self.mainWin.actionOpen, SIGNAL("triggered()"), self.onOpen) self.connect(m.actionNew, s, self.onNew)
self.connect(self.mainWin.actionOpenSamples, SIGNAL("triggered()"), self.onOpenSamples) self.connect(m.actionOpenOnline, s, self.onOpenOnline)
self.connect(self.mainWin.actionSave, SIGNAL("triggered()"), self.onSave) self.connect(m.actionOpen, s, self.onOpen)
self.connect(self.mainWin.actionSaveAs, SIGNAL("triggered()"), self.onSaveAs) self.connect(m.actionOpenSamples, s, self.onOpenSamples)
self.connect(self.mainWin.actionClose, SIGNAL("triggered()"), self.saveAndClose) self.connect(m.actionSave, s, self.onSave)
self.connect(self.mainWin.actionExit, SIGNAL("triggered()"), self, SLOT("close()")) self.connect(m.actionSaveAs, s, self.onSaveAs)
self.connect(self.mainWin.actionSyncdeck, SIGNAL("triggered()"), self.syncDeck) self.connect(m.actionClose, s, self.saveAndClose)
self.connect(self.mainWin.actionDeckProperties, SIGNAL("triggered()"), self.onDeckProperties) self.connect(m.actionExit, s, self, SLOT("close()"))
self.connect(self.mainWin.actionDisplayProperties, SIGNAL("triggered()"),self.onDisplayProperties) self.connect(m.actionSyncdeck, s, self.syncDeck)
self.connect(self.mainWin.actionAddcards, SIGNAL("triggered()"), self.onAddCard) self.connect(m.actionDeckProperties, s, self.onDeckProperties)
self.connect(self.mainWin.actionEditdeck, SIGNAL("triggered()"), self.onEditDeck) self.connect(m.actionDisplayProperties, s,self.onDisplayProperties)
self.connect(self.mainWin.actionPreferences, SIGNAL("triggered()"), self.onPrefs) self.connect(m.actionAddcards, s, self.onAddCard)
self.connect(self.mainWin.actionLookup_es, SIGNAL("triggered()"), self.onLookupEdictSelection) self.connect(m.actionEditdeck, s, self.onEditDeck)
self.connect(self.mainWin.actionLookup_esk, SIGNAL("triggered()"), self.onLookupEdictKanjiSelection) self.connect(m.actionPreferences, s, self.onPrefs)
self.connect(self.mainWin.actionLookup_expr, SIGNAL("triggered()"), self.onLookupExpression) self.connect(m.actionLookup_es, s, self.onLookupEdictSelection)
self.connect(self.mainWin.actionLookup_mean, SIGNAL("triggered()"), self.onLookupMeaning) self.connect(m.actionLookup_esk, s, self.onLookupEdictKanjiSelection)
self.connect(self.mainWin.actionLookup_as, SIGNAL("triggered()"), self.onLookupAlcSelection) self.connect(m.actionLookup_expr, s, self.onLookupExpression)
self.connect(self.mainWin.actionDstats, SIGNAL("triggered()"), self.onDeckStats) self.connect(m.actionLookup_mean, s, self.onLookupMeaning)
self.connect(self.mainWin.actionKstats, SIGNAL("triggered()"), self.onKanjiStats) self.connect(m.actionLookup_as, s, self.onLookupAlcSelection)
self.connect(self.mainWin.actionCstats, SIGNAL("triggered()"), self.onCardStats) self.connect(m.actionDstats, s, self.onDeckStats)
self.connect(self.mainWin.actionGraphs, SIGNAL("triggered()"), self.onShowGraph) self.connect(m.actionKstats, s, self.onKanjiStats)
self.connect(self.mainWin.actionAbout, SIGNAL("triggered()"), self.onAbout) self.connect(m.actionCstats, s, self.onCardStats)
self.connect(self.mainWin.actionReportbug, SIGNAL("triggered()"), self.onReportBug) self.connect(m.actionGraphs, s, self.onShowGraph)
self.connect(self.mainWin.actionForum, SIGNAL("triggered()"), self.onForum) self.connect(m.actionAbout, s, self.onAbout)
self.connect(self.mainWin.actionStarthere, SIGNAL("triggered()"), self.onStartHere) self.connect(m.actionReportbug, s, self.onReportBug)
self.connect(self.mainWin.actionImport, SIGNAL("triggered()"), self.onImport) self.connect(m.actionForum, s, self.onForum)
self.connect(self.mainWin.actionExport, SIGNAL("triggered()"), self.onExport) self.connect(m.actionStarthere, s, self.onStartHere)
self.connect(self.mainWin.actionMarkCard, SIGNAL("toggled(bool)"), self.onMark) self.connect(m.actionImport, s, self.onImport)
self.connect(self.mainWin.actionSuspendCard, SIGNAL("triggered()"), self.onSuspend) self.connect(m.actionExport, s, self.onExport)
self.connect(self.mainWin.actionModelProperties, SIGNAL("triggered()"), self.onModelProperties) self.connect(m.actionMarkCard, SIGNAL("toggled(bool)"), self.onMark)
self.connect(self.mainWin.actionRepeatQuestionAudio, SIGNAL("triggered()"), self.onRepeatQuestion) self.connect(m.actionSuspendCard, s, self.onSuspend)
self.connect(self.mainWin.actionRepeatAnswerAudio, SIGNAL("triggered()"), self.onRepeatAnswer) self.connect(m.actionModelProperties, s, self.onModelProperties)
self.connect(self.mainWin.actionRepeatAudio, SIGNAL("triggered()"), self.onRepeatAudio) self.connect(m.actionRepeatQuestionAudio, s, self.onRepeatQuestion)
self.connect(self.mainWin.actionUndoAnswer, SIGNAL("triggered()"), self.onUndoAnswer) self.connect(m.actionRepeatAnswerAudio, s, self.onRepeatAnswer)
self.connect(self.mainWin.actionCheckDatabaseIntegrity, SIGNAL("triggered()"), self.onCheckDB) self.connect(m.actionRepeatAudio, s, self.onRepeatAudio)
self.connect(self.mainWin.actionOptimizeDatabase, SIGNAL("triggered()"), self.onOptimizeDB) self.connect(m.actionUndoAnswer, s, self.onUndoAnswer)
self.connect(self.mainWin.actionMergeModels, SIGNAL("triggered()"), self.onMergeModels) self.connect(m.actionCheckDatabaseIntegrity, s, self.onCheckDB)
self.connect(self.mainWin.actionCheckMediaDatabase, SIGNAL("triggered()"), self.onCheckMediaDB) self.connect(m.actionOptimizeDatabase, s, self.onOptimizeDB)
self.connect(m.actionMergeModels, s, self.onMergeModels)
self.connect(m.actionCheckMediaDatabase, s, self.onCheckMediaDB)
def enableDeckMenuItems(self, enabled=True): def enableDeckMenuItems(self, enabled=True):
"setEnabled deck-related items." "setEnabled deck-related items."

View file

@ -192,6 +192,8 @@ class AddModel(QDialog):
# the list widget will swallow the enter key # the list widget will swallow the enter key
s = QShortcut(QKeySequence("Return"), self) s = QShortcut(QKeySequence("Return"), self)
self.connect(s, SIGNAL("activated()"), self.accept) self.connect(s, SIGNAL("activated()"), self.accept)
# help
self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"), self.onHelp)
def getModel(self): def getModel(self):
self.exec_() self.exec_()
@ -202,3 +204,6 @@ class AddModel(QDialog):
unicode(self.dialog.models.currentItem().text())] unicode(self.dialog.models.currentItem().text())]
QDialog.accept(self) QDialog.accept(self)
def onHelp(self):
QDesktopServices.openUrl(QUrl(ankiqt.appWiki +
"AddModel"))

View file

@ -9,6 +9,10 @@ import anki
from anki.models import FieldModel, CardModel from anki.models import FieldModel, CardModel
from ankiqt import ui from ankiqt import ui
tabs = ("General",
"Fields",
"Cards")
class ModelProperties(QDialog): class ModelProperties(QDialog):
def __init__(self, parent, model, main=None, onFinish=None): def __init__(self, parent, model, main=None, onFinish=None):
@ -22,6 +26,8 @@ class ModelProperties(QDialog):
self.onFinish = onFinish self.onFinish = onFinish
self.dialog = ankiqt.forms.modelproperties.Ui_ModelProperties() self.dialog = ankiqt.forms.modelproperties.Ui_ModelProperties()
self.dialog.setupUi(self) self.dialog.setupUi(self)
self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"),
self.helpRequested)
self.setupFields() self.setupFields()
self.setupCards() self.setupCards()
self.readData() self.readData()
@ -431,6 +437,12 @@ class ModelProperties(QDialog):
self.updateCards(row + 1) self.updateCards(row + 1)
self.ignoreCardUpdate = False self.ignoreCardUpdate = False
def helpRequested(self):
idx = self.dialog.tabWidget.currentIndex()
QDesktopServices.openUrl(QUrl(ankiqt.appWiki +
"ModelProperties#" +
tabs[idx]))
# Cleanup # Cleanup
########################################################################## ##########################################################################

View file

@ -11,6 +11,10 @@ from anki.stdmodels import JapaneseModel
from ankiqt import ui from ankiqt import ui
import ankiqt.forms import ankiqt.forms
tabs = ("Display",
"SaveAndSync",
"Advanced")
class Preferences(QDialog): class Preferences(QDialog):
def __init__(self, parent, config): def __init__(self, parent, config):
@ -30,6 +34,7 @@ class Preferences(QDialog):
(_("Korean"), "ko_KR"), (_("Korean"), "ko_KR"),
(_("Spanish"), "es_ES"), (_("Spanish"), "es_ES"),
] ]
self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"), self.helpRequested)
self.setupLang() self.setupLang()
self.setupFont() self.setupFont()
self.setupColour() self.setupColour()
@ -158,32 +163,29 @@ class Preferences(QDialog):
def setupAdvanced(self): def setupAdvanced(self):
self.dialog.showToolbar.setChecked(self.config['showToolbar']) self.dialog.showToolbar.setChecked(self.config['showToolbar'])
self.dialog.compactEaseButtons.setChecked( self.dialog.compactEaseButtons.setChecked(
self.config['easeButtonStyle'] != 'standard') self.config['show3AnswerButtons'])
self.dialog.tallButtons.setChecked( self.dialog.tallButtons.setChecked(
self.config['easeButtonHeight'] != 'standard') self.config['easeButtonHeight'] != 'standard')
self.dialog.suppressEstimates.setChecked(self.config['suppressEstimates']) self.dialog.suppressEstimates.setChecked(self.config['suppressEstimates'])
self.dialog.suppressLastCardInterval.setChecked(self.config['suppressLastCardInterval']) self.dialog.showLastCardInterval.setChecked(self.config['showLastCardInterval'])
self.dialog.suppressLastCardContent.setChecked(self.config['suppressLastCardContent']) self.dialog.showLastCardContent.setChecked(self.config['showLastCardContent'])
self.dialog.showTray.setChecked(self.config['showTray']) self.dialog.showTray.setChecked(self.config['showTrayIcon'])
self.dialog.showTimer.setChecked(self.config['showTimer']) self.dialog.showTimer.setChecked(self.config['showTimer'])
self.dialog.editCurrentOnly.setChecked(self.config['editCurrentOnly']) self.dialog.simpleToolbar.setChecked(self.config['simpleToolbar'])
def updateAdvanced(self): def updateAdvanced(self):
self.config['showToolbar'] = self.dialog.showToolbar.isChecked() self.config['showToolbar'] = self.dialog.showToolbar.isChecked()
if self.dialog.compactEaseButtons.isChecked(): self.config['show3AnswerButtons'] = self.dialog.compactEaseButtons.isChecked()
self.config['easeButtonStyle'] = 'compact'
else:
self.config['easeButtonStyle'] = 'standard'
if self.dialog.tallButtons.isChecked(): if self.dialog.tallButtons.isChecked():
self.config['easeButtonHeight'] = 'tall' self.config['easeButtonHeight'] = 'tall'
else: else:
self.config['easeButtonHeight'] = 'standard' self.config['easeButtonHeight'] = 'standard'
self.config['suppressLastCardInterval'] = self.dialog.suppressLastCardInterval.isChecked() self.config['showLastCardInterval'] = self.dialog.showLastCardInterval.isChecked()
self.config['suppressLastCardContent'] = self.dialog.suppressLastCardContent.isChecked() self.config['showLastCardContent'] = self.dialog.showLastCardContent.isChecked()
self.config['showTray'] = self.dialog.showTray.isChecked() self.config['showTrayIcon'] = self.dialog.showTray.isChecked()
self.config['showTimer'] = self.dialog.showTimer.isChecked() self.config['showTimer'] = self.dialog.showTimer.isChecked()
self.config['suppressEstimates'] = self.dialog.suppressEstimates.isChecked() self.config['suppressEstimates'] = self.dialog.suppressEstimates.isChecked()
self.config['editCurrentOnly'] = self.dialog.editCurrentOnly.isChecked() self.config['simpleToolbar'] = self.dialog.simpleToolbar.isChecked()
def codeToIndex(self, code): def codeToIndex(self, code):
n = 0 n = 0
@ -193,3 +195,9 @@ class Preferences(QDialog):
n += 1 n += 1
# default to english # default to english
return self.codeToIndex("en_US") return self.codeToIndex("en_US")
def helpRequested(self):
idx = self.dialog.tabWidget.currentIndex()
QDesktopServices.openUrl(QUrl(ankiqt.appWiki +
"Preferences#" +
tabs[idx]))

View file

@ -248,13 +248,9 @@ You should aim to answer each question within<br>
if self.main.state in "showQuestion": if self.main.state in "showQuestion":
t = self.main.currentCard.thinkingTime() t = self.main.currentCard.thinkingTime()
if t < 60: if t < 60:
if t < StatusView.warnTime: self.timer.setText('00:%02d' % t)
col="#000000"
else:
col="#FF3300"
self.timer.setText('<font color="%s">00:%02d</font>' % (col, t))
else: else:
self.timer.setText('<font color="#FF0000"><b>01:00</b></font>') self.timer.setText('01:00')
elif self.main.state == "showAnswer": elif self.main.state == "showAnswer":
pass pass
else: else:
@ -262,4 +258,4 @@ You should aim to answer each question within<br>
def onConfigure(self): def onConfigure(self):
self.main.deckProperties = ui.deckproperties.DeckProperties(self.main) self.main.deckProperties = ui.deckproperties.DeckProperties(self.main)
self.main.deckProperties.dialog.qtabwidget.setCurrentIndex(2) self.main.deckProperties.dialog.qtabwidget.setCurrentIndex(1)

View file

@ -14,7 +14,7 @@ class AnkiTrayIcon( QtCore.QObject ):
self.mw = mw self.mw = mw
self.anki_visible = True self.anki_visible = True
if (QtGui.QSystemTrayIcon.isSystemTrayAvailable() and if (QtGui.QSystemTrayIcon.isSystemTrayAvailable() and
mw.config['showTray']): mw.config['showTrayIcon']):
self.ti = QtGui.QSystemTrayIcon( mw ) self.ti = QtGui.QSystemTrayIcon( mw )
if self.ti: if self.ti:
self.mw.addHook("quit", self.onQuit) self.mw.addHook("quit", self.onQuit)

View file

@ -36,7 +36,7 @@ class View(object):
return return
elif self.state == "noDeck": elif self.state == "noDeck":
self.clearWindow() self.clearWindow()
self.drawNoDeckMessage() self.drawWelcomeMessage()
self.flush() self.flush()
return return
self.redisplay() self.redisplay()
@ -50,8 +50,8 @@ class View(object):
self.maybeHelp() self.maybeHelp()
if self.main.deck.cardCount(): if self.main.deck.cardCount():
if not self.main.lastCard or ( if not self.main.lastCard or (
self.main.config['suppressLastCardContent'] and not self.main.config['showLastCardContent'] and
self.main.config['suppressLastCardInterval']): not self.main.config['showLastCardInterval']):
self.buffer += "<br>" self.buffer += "<br>"
else: else:
self.drawTopSection() self.drawTopSection()
@ -62,7 +62,7 @@ class View(object):
self.drawQuestion(nosound=True) self.drawQuestion(nosound=True)
self.drawAnswer() self.drawAnswer()
elif self.state == "deckEmpty": elif self.state == "deckEmpty":
self.drawDeckEmptyMessage() self.drawWelcomeMessage()
elif self.state == "deckFinished": elif self.state == "deckFinished":
self.drawDeckFinishedMessage() self.drawDeckFinishedMessage()
self.flush() self.flush()
@ -138,7 +138,7 @@ class View(object):
def drawLastCard(self): def drawLastCard(self):
"Show the last card if not the current one, and next time." "Show the last card if not the current one, and next time."
if self.main.lastCard: if self.main.lastCard:
if not self.main.config['suppressLastCardContent']: if self.main.config['showLastCardContent']:
if (self.state == "deckFinished" or if (self.state == "deckFinished" or
self.main.currentCard.id != self.main.lastCard.id): self.main.currentCard.id != self.main.lastCard.id):
q = self.main.lastCard.question.replace("<br>", " ") q = self.main.lastCard.question.replace("<br>", " ")
@ -152,7 +152,7 @@ class View(object):
s = "%s<br>%s" % (q, a) s = "%s<br>%s" % (q, a)
s = stripLatex(s) s = stripLatex(s)
self.write('<span class="lastCard">%s</span><br>' % s) self.write('<span class="lastCard">%s</span><br>' % s)
if not self.main.config['suppressLastCardInterval']: if self.main.config['showLastCardInterval']:
if self.main.lastQuality > 1: if self.main.lastQuality > 1:
msg = _("Well done! This card will appear again in " msg = _("Well done! This card will appear again in "
"<b>%(next)s</b>.") % \ "<b>%(next)s</b>.") % \
@ -162,6 +162,7 @@ class View(object):
"<b>%(next)s</b>.") % \ "<b>%(next)s</b>.") % \
{"next":self.main.lastScheduledTime} {"next":self.main.lastScheduledTime}
self.write(msg) self.write(msg)
self.write("<br>")
# Help # Help
########################################################################## ##########################################################################
@ -189,39 +190,47 @@ class View(object):
# Welcome/empty/finished deck messages # Welcome/empty/finished deck messages
########################################################################## ##########################################################################
def drawNoDeckMessage(self): def drawWelcomeMessage(self):
self.write(_("""<h1>Welcome to Anki!</h1> self.write(_("""
<h1>Welcome to Anki!</h1>
<p> <p>
<table> <table>
<tr>
<td width=50>
<a href="welcome:addfacts"><img src=":/icons/list-add.png"></a>
</td>
<td valign=middle><h1><a href="welcome:addfacts">Add material</a></h1>
Start adding your own material.</td>
</tr>
</table>
<br>
<table>
<tr> <tr>
<td> <td>
<a href="welcome:new"><img src=":/icons/document-new.png"></a> <a href="welcome:open"><img src=":/icons/document-open.png"></a>
</td> </td>
<td valign=middle> <td valign=middle><h2><a href="welcome:open">Open Local Deck</a></h2></td>
<h2><a href="welcome:new">Create a new deck</a></h2></td> </tr>
<tr>
<td>
<a href="welcome:openrem"><img src=":/icons/document-open-remote.png"></a>
</td>
<td valign=middle><h2><a href="welcome:openrem">Open Online Deck</a></h2></td>
</tr> </tr>
<tr> <tr>
<td width=50> <td width=50>
<a href="welcome:sample"><img src=":/icons/anki.png"></a> <a href="welcome:sample"><img src=":/icons/anki.png"></a>
</td> </td>
<td valign=middle><h2><a href="welcome:sample">Open a sample deck</a></h2></td> <td valign=middle><h2><a href="welcome:sample">Open Sample Deck</a></h2></td>
</tr> </tr>
<tr> </table>"""))
<td>
<a href="welcome:open"><img src=":/icons/document-open.png"></a>
</td>
<td valign=middle><h2><a href="welcome:open">Open an existing deck</a></h2></td>
</tr>
</table>
"""))
def drawDeckEmptyMessage(self):
"Tell the user the deck is empty."
self.write(_("""
<h1>Empty deck</h1>The current deck has no cards in it. Please select 'Add
card' from the Edit menu."""))
def drawDeckFinishedMessage(self): def drawDeckFinishedMessage(self):
"Tell the user the deck is finished." "Tell the user the deck is finished."

View file

@ -5,8 +5,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>388</width> <width>285</width>
<height>456</height> <height>269</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle" >

View file

@ -29,8 +29,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>413</width> <width>407</width>
<height>385</height> <height>373</height>
</rect> </rect>
</property> </property>
<attribute name="title" > <attribute name="title" >
@ -72,7 +72,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" > <item row="4" column="0" >
<widget class="QLabel" name="label_28" > <widget class="QLabel" name="label_28" >
<property name="maximumSize" > <property name="maximumSize" >
<size> <size>
@ -81,38 +81,48 @@
</size> </size>
</property> </property>
<property name="text" > <property name="text" >
<string>&lt;h1>Sources&lt;h1></string> <string>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
p, li { white-space: pre-wrap; }
&lt;/style>&lt;/head>&lt;body style=" font-family:'Arial'; font-size:8pt; font-weight:400; font-style:normal;">
&lt;p style=" margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:xx-large; font-weight:600;">&lt;span style=" font-size:xx-large;">Sources&lt;/span>&lt;/p>&lt;/body>&lt;/html></string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0" > <item row="6" column="0" >
<widget class="QListWidget" name="listWidget" />
</item>
<item row="5" column="0" >
<layout class="QHBoxLayout" name="horizontalLayout_3" > <layout class="QHBoxLayout" name="horizontalLayout_3" >
<item> <item>
<widget class="QPushButton" name="addSource" > <widget class="QPushButton" name="addSource" >
<property name="text" > <property name="text" >
<string>Add Source</string> <string>&amp;Add Source</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="editSource" >
<property name="text" >
<string>Edit Source</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="deleteSource" > <widget class="QPushButton" name="deleteSource" >
<property name="text" > <property name="text" >
<string>Delete Source</string> <string>&amp;Delete Source</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item row="5" column="0" >
<widget class="QTableWidget" name="sourcesTable" />
</item>
<item row="3" column="0" >
<spacer name="verticalSpacer_4" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -633,9 +643,8 @@
<tabstop>qtabwidget</tabstop> <tabstop>qtabwidget</tabstop>
<tabstop>doSync</tabstop> <tabstop>doSync</tabstop>
<tabstop>syncName</tabstop> <tabstop>syncName</tabstop>
<tabstop>listWidget</tabstop> <tabstop>sourcesTable</tabstop>
<tabstop>addSource</tabstop> <tabstop>addSource</tabstop>
<tabstop>editSource</tabstop>
<tabstop>deleteSource</tabstop> <tabstop>deleteSource</tabstop>
<tabstop>newCardsPerDay</tabstop> <tabstop>newCardsPerDay</tabstop>
<tabstop>failedCardMax</tabstop> <tabstop>failedCardMax</tabstop>

View file

@ -6,7 +6,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>543</width> <width>543</width>
<height>457</height> <height>285</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy" > <property name="sizePolicy" >
@ -28,7 +28,7 @@
<x>0</x> <x>0</x>
<y>53</y> <y>53</y>
<width>543</width> <width>543</width>
<height>384</height> <height>212</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy" > <property name="sizePolicy" >
@ -194,7 +194,7 @@
<item> <item>
<widget class="QFrame" name="innerHelpFrame" > <widget class="QFrame" name="innerHelpFrame" >
<property name="sizePolicy" > <property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Expanding" > <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -285,7 +285,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="sizePolicy" > <property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" > <sizepolicy vsizetype="Expanding" hsizetype="Fixed" >
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -472,7 +472,7 @@
<property name="geometry" > <property name="geometry" >
<rect> <rect>
<x>0</x> <x>0</x>
<y>437</y> <y>265</y>
<width>543</width> <width>543</width>
<height>20</height> <height>20</height>
</rect> </rect>

View file

@ -5,8 +5,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>532</width> <width>322</width>
<height>531</height> <height>417</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle" >
@ -23,12 +23,12 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>510</width> <width>306</width>
<height>449</height> <height>351</height>
</rect> </rect>
</property> </property>
<attribute name="title" > <attribute name="title" >
<string>Language, Fonts and Colours</string> <string>Display</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout" > <layout class="QVBoxLayout" name="verticalLayout" >
<item> <item>
@ -42,7 +42,7 @@
<item> <item>
<widget class="QLabel" name="label" > <widget class="QLabel" name="label" >
<property name="text" > <property name="text" >
<string>&lt;h1>Interface language&lt;/h1>The language for the user interface: dialogs, menus, etc.</string> <string>&lt;h1>Language&lt;/h1></string>
</property> </property>
<property name="wordWrap" > <property name="wordWrap" >
<bool>false</bool> <bool>false</bool>
@ -68,7 +68,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text" > <property name="text" >
<string>&lt;h1>Standard fonts&lt;/h1>See 'display properties' for deck specific font preferences.</string> <string>&lt;h1>Fonts&lt;/h1></string>
</property> </property>
<property name="wordWrap" > <property name="wordWrap" >
<bool>false</bool> <bool>false</bool>
@ -169,7 +169,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text" > <property name="text" >
<string>&lt;h1>Standard colours&lt;/h1>These colours are used for all decks.</string> <string>&lt;h1>Colours&lt;/h1></string>
</property> </property>
<property name="wordWrap" > <property name="wordWrap" >
<bool>false</bool> <bool>false</bool>
@ -250,12 +250,12 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>453</width> <width>306</width>
<height>443</height> <height>351</height>
</rect> </rect>
</property> </property>
<attribute name="title" > <attribute name="title" >
<string>Autosave and Synchronisation</string> <string>Save &amp;&amp; Sync</string>
</attribute> </attribute>
<layout class="QVBoxLayout" > <layout class="QVBoxLayout" >
<property name="spacing" > <property name="spacing" >
@ -283,7 +283,7 @@
<item> <item>
<widget class="QLabel" name="label_4" > <widget class="QLabel" name="label_4" >
<property name="text" > <property name="text" >
<string>&lt;h1>Autosaving&lt;/h1>Anki can save your progress automatically.</string> <string>&lt;h1>Autosaving&lt;/h1></string>
</property> </property>
</widget> </widget>
</item> </item>
@ -350,7 +350,7 @@
<item> <item>
<widget class="QLabel" name="label_16" > <widget class="QLabel" name="label_16" >
<property name="text" > <property name="text" >
<string>&lt;h1>Synchronisation&lt;/h1>Synchronisation enables you to access your deck from the web and your mobile phone. You can &lt;a href="http://anki.ichi2.net/">create a free account&lt;/a>.</string> <string>&lt;h1>Synchronisation&lt;/h1>&lt;a href="http://anki.ichi2.net/">Create a free account&lt;/a>.</string>
</property> </property>
<property name="wordWrap" > <property name="wordWrap" >
<bool>true</bool> <bool>true</bool>
@ -419,7 +419,7 @@
</layout> </layout>
</item> </item>
<item> <item>
<spacer> <spacer name="verticalSpacer_2" >
<property name="orientation" > <property name="orientation" >
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -438,30 +438,16 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>453</width> <width>306</width>
<height>443</height> <height>351</height>
</rect> </rect>
</property> </property>
<attribute name="title" > <attribute name="title" >
<string>Advanced Settings</string> <string>Advanced</string>
</attribute> </attribute>
<layout class="QVBoxLayout" > <layout class="QVBoxLayout" >
<item> <item>
<layout class="QGridLayout" > <layout class="QGridLayout" >
<item row="1" column="0" >
<widget class="QCheckBox" name="showToolbar" >
<property name="text" >
<string>Show toolbar on startup</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QCheckBox" name="compactEaseButtons" >
<property name="text" >
<string>Use compact answer button style</string>
</property>
</widget>
</item>
<item row="0" column="0" > <item row="0" column="0" >
<widget class="QLabel" name="label_6" > <widget class="QLabel" name="label_6" >
<property name="text" > <property name="text" >
@ -469,55 +455,66 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" > <item row="1" column="0" >
<widget class="QCheckBox" name="tallButtons" > <widget class="QCheckBox" name="compactEaseButtons" >
<property name="text" > <property name="text" >
<string>Tall buttons (for touchscreen)</string> <string>Show 3 answer buttons, not 5</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="showTimer" >
<property name="text" >
<string>Show timer</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0" > <item row="4" column="0" >
<widget class="QCheckBox" name="editCurrentOnly" >
<property name="text" >
<string>Start Edit Deck with only current card selected</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0" >
<widget class="QCheckBox" name="suppressEstimates" > <widget class="QCheckBox" name="suppressEstimates" >
<property name="text" > <property name="text" >
<string>Hide next interval when showing answer buttons</string> <string>Hide next interval when showing answer buttons</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0" > <item row="5" column="0" >
<widget class="QCheckBox" name="suppressLastCardInterval" > <widget class="QCheckBox" name="showLastCardContent" >
<property name="text" > <property name="text" >
<string>Hide interval of last card</string> <string>Show last card's question/answer</string>
</property>
</widget>
</item>
<item row="6" column="0" >
<widget class="QCheckBox" name="showLastCardInterval" >
<property name="text" >
<string>Show last card's interval</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0" > <item row="7" column="0" >
<widget class="QCheckBox" name="suppressLastCardContent" > <widget class="QCheckBox" name="showToolbar" >
<property name="text" > <property name="text" >
<string>Hide question/answer of last card</string> <string>Show toolbar on startup</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0" > <item row="8" column="0" >
<widget class="QCheckBox" name="tallButtons" >
<property name="text" >
<string>Tall buttons (for touchscreen)</string>
</property>
</widget>
</item>
<item row="9" column="0" >
<widget class="QCheckBox" name="showTray" > <widget class="QCheckBox" name="showTray" >
<property name="text" > <property name="text" >
<string>Show tray icon</string> <string>Show tray icon</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0" > <item row="2" column="0" >
<widget class="QCheckBox" name="showTimer" > <widget class="QCheckBox" name="simpleToolbar" >
<property name="text" > <property name="text" >
<string>Show timer</string> <string>Simple toolbar</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -546,11 +543,13 @@
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="standardButtons" > <property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
<zorder>buttonBox</zorder>
<zorder>tabWidget</zorder>
</widget> </widget>
<tabstops> <tabstops>
<tabstop>tabWidget</tabstop> <tabstop>tabWidget</tabstop>
@ -573,6 +572,15 @@
<tabstop>syncPass</tabstop> <tabstop>syncPass</tabstop>
<tabstop>syncOnOpen</tabstop> <tabstop>syncOnOpen</tabstop>
<tabstop>syncOnClose</tabstop> <tabstop>syncOnClose</tabstop>
<tabstop>compactEaseButtons</tabstop>
<tabstop>simpleToolbar</tabstop>
<tabstop>showTimer</tabstop>
<tabstop>suppressEstimates</tabstop>
<tabstop>showLastCardContent</tabstop>
<tabstop>showLastCardInterval</tabstop>
<tabstop>showToolbar</tabstop>
<tabstop>tallButtons</tabstop>
<tabstop>showTray</tabstop>
<tabstop>buttonBox</tabstop> <tabstop>buttonBox</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>