mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
finish fields dialog
This commit is contained in:
parent
4eba9eb913
commit
b9522487ad
8 changed files with 152 additions and 602 deletions
|
@ -299,7 +299,7 @@ class StatusDelegate(QItemDelegate):
|
||||||
class Browser(QMainWindow):
|
class Browser(QMainWindow):
|
||||||
|
|
||||||
def __init__(self, mw):
|
def __init__(self, mw):
|
||||||
QMainWindow.__init__(self, None)
|
QMainWindow.__init__(self, mw)
|
||||||
#applyStyles(self)
|
#applyStyles(self)
|
||||||
self.mw = mw
|
self.mw = mw
|
||||||
self.col = self.mw.col
|
self.col = self.mw.col
|
||||||
|
@ -491,8 +491,8 @@ class Browser(QMainWindow):
|
||||||
self.onRowChanged)
|
self.onRowChanged)
|
||||||
|
|
||||||
def setupEditor(self):
|
def setupEditor(self):
|
||||||
self.editor = aqt.editor.Editor(self.mw,
|
self.editor = aqt.editor.Editor(
|
||||||
self.form.fieldsArea)
|
self.mw, self.form.fieldsArea, self)
|
||||||
self.editor.stealFocus = False
|
self.editor.stealFocus = False
|
||||||
|
|
||||||
def onRowChanged(self, current, previous):
|
def onRowChanged(self, current, previous):
|
||||||
|
@ -534,7 +534,7 @@ class Browser(QMainWindow):
|
||||||
|
|
||||||
def onSortChanged(self, idx, ord):
|
def onSortChanged(self, idx, ord):
|
||||||
type = self.model.activeCols[idx]
|
type = self.model.activeCols[idx]
|
||||||
noSort = ("question", "answer", "template", "cardGroup", "noteGroup")
|
noSort = ("question", "answer", "template", "deck", "ndeck")
|
||||||
if type in noSort:
|
if type in noSort:
|
||||||
showInfo(_("Sorting on this column is not supported. Please "
|
showInfo(_("Sorting on this column is not supported. Please "
|
||||||
"choose another."))
|
"choose another."))
|
||||||
|
|
|
@ -191,7 +191,7 @@ Please create a new card first."""))
|
||||||
n = len(self.cards)
|
n = len(self.cards)
|
||||||
cur = self.card.template()['ord']+1
|
cur = self.card.template()['ord']+1
|
||||||
pos = getOnlyText(
|
pos = getOnlyText(
|
||||||
_("Enter new card position (1..%s):") % n,
|
_("Enter new card position (1...%s):") % n,
|
||||||
default=str(cur))
|
default=str(cur))
|
||||||
if not pos:
|
if not pos:
|
||||||
return
|
return
|
||||||
|
|
|
@ -192,9 +192,10 @@ $(function () {
|
||||||
|
|
||||||
# caller is responsible for resetting note on reset
|
# caller is responsible for resetting note on reset
|
||||||
class Editor(object):
|
class Editor(object):
|
||||||
def __init__(self, mw, widget, addMode=False):
|
def __init__(self, mw, widget, parentWindow, addMode=False):
|
||||||
self.widget = widget
|
|
||||||
self.mw = mw
|
self.mw = mw
|
||||||
|
self.widget = widget
|
||||||
|
self.parentWindow = parentWindow
|
||||||
self.note = None
|
self.note = None
|
||||||
self.stealFocus = True
|
self.stealFocus = True
|
||||||
self.addMode = addMode
|
self.addMode = addMode
|
||||||
|
@ -233,7 +234,7 @@ class Editor(object):
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
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, native=False):
|
||||||
b = QPushButton(text)
|
b = QPushButton(text)
|
||||||
if check:
|
if check:
|
||||||
b.connect(b, SIGNAL("clicked(bool)"), func)
|
b.connect(b, SIGNAL("clicked(bool)"), func)
|
||||||
|
@ -242,6 +243,7 @@ class Editor(object):
|
||||||
if size:
|
if size:
|
||||||
b.setFixedHeight(20)
|
b.setFixedHeight(20)
|
||||||
b.setFixedWidth(20)
|
b.setFixedWidth(20)
|
||||||
|
if not native:
|
||||||
b.setStyle(self.plastiqueStyle)
|
b.setStyle(self.plastiqueStyle)
|
||||||
b.setFocusPolicy(Qt.NoFocus)
|
b.setFocusPolicy(Qt.NoFocus)
|
||||||
if not text:
|
if not text:
|
||||||
|
@ -266,13 +268,15 @@ class Editor(object):
|
||||||
self.iconsBox.setMargin(0)
|
self.iconsBox.setMargin(0)
|
||||||
self.iconsBox.setSpacing(0)
|
self.iconsBox.setSpacing(0)
|
||||||
self.outerLayout.addLayout(self.iconsBox)
|
self.outerLayout.addLayout(self.iconsBox)
|
||||||
# align to right
|
|
||||||
self.iconsBox.addItem(QSpacerItem(20,1, QSizePolicy.Expanding))
|
|
||||||
b = self._addButton
|
b = self._addButton
|
||||||
b("fields", self.onFields, "Ctrl+f",
|
b("fields", self.onFields, "Ctrl+f",
|
||||||
shortcut(_("Layout (Ctrl+f)")), size=False, text=_("Fields"))
|
shortcut(_("Layout (Ctrl+f)")), size=False, text=_("Fields..."),
|
||||||
|
native=True)
|
||||||
b("layout", self.onCardLayout, "Ctrl+l",
|
b("layout", self.onCardLayout, "Ctrl+l",
|
||||||
shortcut(_("Layout (Ctrl+l)")), size=False, text=_("Layout"))
|
shortcut(_("Layout (Ctrl+l)")), size=False, text=_("Layout..."),
|
||||||
|
native=True)
|
||||||
|
# align to right
|
||||||
|
self.iconsBox.addItem(QSpacerItem(20,1, QSizePolicy.Expanding))
|
||||||
b("text_bold", self.toggleBold, "Ctrl+b", _("Bold text (Ctrl+b)"),
|
b("text_bold", self.toggleBold, "Ctrl+b", _("Bold text (Ctrl+b)"),
|
||||||
check=True)
|
check=True)
|
||||||
b("text_italic", self.toggleItalic, "Ctrl+i", _("Italic text (Ctrl+i)"),
|
b("text_italic", self.toggleItalic, "Ctrl+i", _("Italic text (Ctrl+i)"),
|
||||||
|
@ -311,7 +315,7 @@ class Editor(object):
|
||||||
def onFields(self):
|
def onFields(self):
|
||||||
from aqt.fields import FieldDialog
|
from aqt.fields import FieldDialog
|
||||||
self.saveNow()
|
self.saveNow()
|
||||||
FieldDialog(self.mw, self.note, parent=self.widget)
|
FieldDialog(self.mw, self.note, parent=self.parentWindow)
|
||||||
|
|
||||||
def onCardLayout(self):
|
def onCardLayout(self):
|
||||||
from aqt.clayout import CardLayout
|
from aqt.clayout import CardLayout
|
||||||
|
@ -320,7 +324,7 @@ class Editor(object):
|
||||||
ord = self.card.ord
|
ord = self.card.ord
|
||||||
else:
|
else:
|
||||||
ord = 0
|
ord = 0
|
||||||
CardLayout(self.mw, self.note, ord=ord, parent=self.widget)
|
CardLayout(self.mw, self.note, ord=ord, parent=self.parentWindow)
|
||||||
self.loadNote()
|
self.loadNote()
|
||||||
|
|
||||||
# JS->Python bridge
|
# JS->Python bridge
|
||||||
|
|
473
aqt/fields.py
473
aqt/fields.py
|
@ -5,29 +5,25 @@ from aqt.qt import *
|
||||||
import re
|
import re
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
import aqt
|
import aqt
|
||||||
from aqt.utils import saveGeom, restoreGeom, getBase, mungeQA, \
|
from aqt.utils import showWarning, openHelp, getOnlyText
|
||||||
saveSplitter, restoreSplitter, showInfo, askUser, getText, \
|
|
||||||
openHelp
|
|
||||||
from anki.utils import isMac, isWin
|
|
||||||
|
|
||||||
# raise Exception("Remember to disallow media&latex refs in edit.")
|
|
||||||
|
|
||||||
# need to strip the field management code out of this
|
|
||||||
|
|
||||||
class FieldDialog(QDialog):
|
class FieldDialog(QDialog):
|
||||||
|
|
||||||
def __init__(self, mw, note, ord=0, parent=None):
|
def __init__(self, mw, note, ord=0, parent=None):
|
||||||
QDialog.__init__(self, parent or mw, Qt.Window)
|
QDialog.__init__(self, parent or mw) #, Qt.Window)
|
||||||
self.mw = aqt.mw
|
self.mw = aqt.mw
|
||||||
self.parent = parent or mw
|
self.parent = parent or mw
|
||||||
self.note = note
|
self.note = note
|
||||||
self.col = self.mw.col
|
self.col = self.mw.col
|
||||||
self.mm = self.mw.col.models
|
self.mm = self.mw.col.models
|
||||||
self.model = note.model()
|
self.model = note.model()
|
||||||
|
self.mw.checkpoint(_("Fields"))
|
||||||
|
self.setWindowModality(Qt.WindowModal)
|
||||||
self.form = aqt.forms.fields.Ui_Dialog()
|
self.form = aqt.forms.fields.Ui_Dialog()
|
||||||
self.form.setupUi(self)
|
self.form.setupUi(self)
|
||||||
self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
|
self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
|
||||||
self.form.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False)
|
self.form.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False)
|
||||||
|
self.currentIdx = None
|
||||||
self.fillFields()
|
self.fillFields()
|
||||||
self.setupSignals()
|
self.setupSignals()
|
||||||
self.form.fieldList.setCurrentRow(0)
|
self.form.fieldList.setCurrentRow(0)
|
||||||
|
@ -36,6 +32,7 @@ class FieldDialog(QDialog):
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def fillFields(self):
|
def fillFields(self):
|
||||||
|
self.currentIdx = None
|
||||||
self.form.fieldList.clear()
|
self.form.fieldList.clear()
|
||||||
for f in self.model['flds']:
|
for f in self.model['flds']:
|
||||||
self.form.fieldList.addItem(f['name'])
|
self.form.fieldList.addItem(f['name'])
|
||||||
|
@ -47,24 +44,80 @@ class FieldDialog(QDialog):
|
||||||
c(f.fieldList, s("currentRowChanged(int)"), self.onRowChange)
|
c(f.fieldList, s("currentRowChanged(int)"), self.onRowChange)
|
||||||
c(f.fieldAdd, s("clicked()"), self.onAdd)
|
c(f.fieldAdd, s("clicked()"), self.onAdd)
|
||||||
c(f.fieldDelete, s("clicked()"), self.onDelete)
|
c(f.fieldDelete, s("clicked()"), self.onDelete)
|
||||||
c(f.fieldUp, s("clicked()"), self.onUp)
|
c(f.fieldRename, s("clicked()"), self.onRename)
|
||||||
c(f.fieldDown, s("clicked()"), self.onDown)
|
c(f.fieldPosition, s("clicked()"), self.onPosition)
|
||||||
c(f.sortField, s("clicked()"), self.onSortField)
|
c(f.sortField, s("clicked()"), self.onSortField)
|
||||||
|
c(f.buttonBox, s("helpRequested()"), self.onHelp)
|
||||||
|
|
||||||
def onRowChange(self, idx):
|
def onRowChange(self, idx):
|
||||||
|
if idx == -1:
|
||||||
|
return
|
||||||
|
self.saveField()
|
||||||
self.loadField(idx)
|
self.loadField(idx)
|
||||||
|
|
||||||
|
def _uniqueName(self, prompt, ignoreOrd=None):
|
||||||
|
txt = getOnlyText(prompt)
|
||||||
|
if not txt:
|
||||||
|
return
|
||||||
|
for f in self.model['flds']:
|
||||||
|
if ignoreOrd is not None and f['ord'] == ignoreOrd:
|
||||||
|
continue
|
||||||
|
if f['name'] == txt:
|
||||||
|
showWarning(_("That field name is already used."))
|
||||||
|
return
|
||||||
|
return txt
|
||||||
|
|
||||||
|
def onRename(self):
|
||||||
|
name = self._uniqueName(_("New name:"), self.currentIdx)
|
||||||
|
if not name:
|
||||||
|
return
|
||||||
|
idx = self.currentIdx
|
||||||
|
f = self.model['flds'][idx]
|
||||||
|
self.mm.renameField(self.model, f, name)
|
||||||
|
self.saveField()
|
||||||
|
self.fillFields()
|
||||||
|
self.form.fieldList.setCurrentRow(idx)
|
||||||
|
|
||||||
def onAdd(self):
|
def onAdd(self):
|
||||||
pass
|
name = self._uniqueName(_("Field name:"))
|
||||||
|
if not name:
|
||||||
|
return
|
||||||
|
self.saveField()
|
||||||
|
self.mw.progress.start()
|
||||||
|
f = self.mm.newField(name)
|
||||||
|
self.mm.addField(self.model, f)
|
||||||
|
self.mw.progress.finish()
|
||||||
|
self.fillFields()
|
||||||
|
self.form.fieldList.setCurrentRow(len(self.model['flds'])-1)
|
||||||
|
|
||||||
def onDelete(self):
|
def onDelete(self):
|
||||||
pass
|
if len(self.model['flds']) < 3:
|
||||||
|
return showWarning(_("Notes require at least two fields."))
|
||||||
|
f = self.model['flds'][self.form.fieldList.currentRow()]
|
||||||
|
self.mw.progress.start()
|
||||||
|
self.mm.remField(self.model, f)
|
||||||
|
self.mw.progress.finish()
|
||||||
|
self.fillFields()
|
||||||
|
self.form.fieldList.setCurrentRow(0)
|
||||||
|
|
||||||
def onUp(self):
|
def onPosition(self, delta=-1):
|
||||||
pass
|
l = len(self.model['flds'])
|
||||||
|
txt = getOnlyText(_("New position (1...%d):") % l)
|
||||||
def onDown(self):
|
if not txt:
|
||||||
pass
|
return
|
||||||
|
try:
|
||||||
|
pos = int(txt)
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
if not 0 < pos <= l:
|
||||||
|
return
|
||||||
|
self.saveField()
|
||||||
|
f = self.model['flds'][self.currentIdx]
|
||||||
|
self.mw.progress.start()
|
||||||
|
self.mm.moveField(self.model, f, pos-1)
|
||||||
|
self.mw.progress.finish()
|
||||||
|
self.fillFields()
|
||||||
|
self.form.fieldList.setCurrentRow(pos-1)
|
||||||
|
|
||||||
def onSortField(self):
|
def onSortField(self):
|
||||||
# don't allow user to disable; it makes no sense
|
# don't allow user to disable; it makes no sense
|
||||||
|
@ -72,389 +125,35 @@ class FieldDialog(QDialog):
|
||||||
self.model['sortf'] = self.form.fieldList.currentRow()
|
self.model['sortf'] = self.form.fieldList.currentRow()
|
||||||
|
|
||||||
def loadField(self, idx):
|
def loadField(self, idx):
|
||||||
|
self.currentIdx = idx
|
||||||
fld = self.model['flds'][idx]
|
fld = self.model['flds'][idx]
|
||||||
f = self.form
|
f = self.form
|
||||||
f.fieldName.setText(fld['name'])
|
|
||||||
f.fontFamily.setCurrentFont(QFont(fld['font']))
|
f.fontFamily.setCurrentFont(QFont(fld['font']))
|
||||||
f.fontSize.setValue(fld['size'])
|
f.fontSize.setValue(fld['size'])
|
||||||
f.sticky.setChecked(fld['sticky'])
|
f.sticky.setChecked(fld['sticky'])
|
||||||
print self.model['sortf'] == fld['ord']
|
|
||||||
f.sortField.setChecked(self.model['sortf'] == fld['ord'])
|
f.sortField.setChecked(self.model['sortf'] == fld['ord'])
|
||||||
f.rtl.setChecked(fld['rtl'])
|
f.rtl.setChecked(fld['rtl'])
|
||||||
|
|
||||||
# Cards & Preview
|
def saveField(self):
|
||||||
##########################################################################
|
# not initialized yet?
|
||||||
|
if self.currentIdx is None:
|
||||||
def setupCards(self):
|
|
||||||
self.updatingCards = False
|
|
||||||
self.playedAudio = {}
|
|
||||||
f = self.form
|
|
||||||
if self.type == 0:
|
|
||||||
f.templateType.setText(
|
|
||||||
_("Templates that will be created:"))
|
|
||||||
elif self.type == 1:
|
|
||||||
f.templateType.setText(
|
|
||||||
_("Templates used by note:"))
|
|
||||||
else:
|
|
||||||
f.templateType.setText(
|
|
||||||
_("All templates:"))
|
|
||||||
# replace with more appropriate size hints
|
|
||||||
for e in ("cardQuestion", "cardAnswer"):
|
|
||||||
w = getattr(f, e)
|
|
||||||
idx = f.templateLayout.indexOf(w)
|
|
||||||
r = f.templateLayout.getItemPosition(idx)
|
|
||||||
f.templateLayout.removeWidget(w)
|
|
||||||
w.hide()
|
|
||||||
w.deleteLater()
|
|
||||||
w = ResizingTextEdit(self)
|
|
||||||
setattr(f, e, w)
|
|
||||||
f.templateLayout.addWidget(w, r[0], r[1])
|
|
||||||
c = self.connect
|
|
||||||
c(f.cardList, SIGNAL("activated(int)"), self.cardChanged)
|
|
||||||
c(f.editTemplates, SIGNAL("clicked()"), self.onEdit)
|
|
||||||
c(f.cardQuestion, SIGNAL("textChanged()"), self.formatChanged)
|
|
||||||
c(f.cardAnswer, SIGNAL("textChanged()"), self.formatChanged)
|
|
||||||
c(f.alignment, SIGNAL("activated(int)"), self.saveCard)
|
|
||||||
c(f.background, SIGNAL("clicked()"),
|
|
||||||
lambda w=f.background:\
|
|
||||||
self.chooseColour(w, "card"))
|
|
||||||
c(f.questionInAnswer, SIGNAL("clicked()"), self.saveCard)
|
|
||||||
c(f.allowEmptyAnswer, SIGNAL("clicked()"), self.saveCard)
|
|
||||||
c(f.typeAnswer, SIGNAL("activated(int)"), self.saveCard)
|
|
||||||
c(f.flipButton, SIGNAL("clicked()"), self.onFlip)
|
|
||||||
c(f.clozectx, SIGNAL("clicked()"), self.saveCard)
|
|
||||||
def linkClicked(url):
|
|
||||||
QDesktopServices.openUrl(QUrl(url))
|
|
||||||
f.preview.page().setLinkDelegationPolicy(
|
|
||||||
QWebPage.DelegateExternalLinks)
|
|
||||||
self.connect(f.preview,
|
|
||||||
SIGNAL("linkClicked(QUrl)"),
|
|
||||||
linkClicked)
|
|
||||||
f.alignment.addItems(alignmentLabels().values())
|
|
||||||
self.typeFieldNames = self.mm.fieldMap(self.model)
|
|
||||||
s = [_("Don't ask me to type in the answer")]
|
|
||||||
s += [_("Compare with field '%s'") % fi
|
|
||||||
for fi in self.typeFieldNames.keys()]
|
|
||||||
f.typeAnswer.insertItems(0, s)
|
|
||||||
|
|
||||||
def formatToScreen(self, fmt):
|
|
||||||
fmt = fmt.replace("}}<br>", "}}\n")
|
|
||||||
return fmt
|
|
||||||
|
|
||||||
def screenToFormat(self, fmt):
|
|
||||||
fmt = fmt.replace("}}\n", "}}<br>")
|
|
||||||
return fmt
|
|
||||||
|
|
||||||
def onEdit(self):
|
|
||||||
aqt.templates.Templates(self.mw, self.model, self)
|
|
||||||
self.reload()
|
|
||||||
|
|
||||||
def formatChanged(self):
|
|
||||||
if self.updatingCards:
|
|
||||||
return
|
return
|
||||||
text = unicode(self.form.cardQuestion.toPlainText())
|
idx = self.currentIdx
|
||||||
self.card.template()['qfmt'] = self.screenToFormat(text)
|
fld = self.model['flds'][idx]
|
||||||
text = unicode(self.form.cardAnswer.toPlainText())
|
|
||||||
self.card.template()['afmt'] = self.screenToFormat(text)
|
|
||||||
self.renderPreview()
|
|
||||||
|
|
||||||
def onFlip(self):
|
|
||||||
q = unicode(self.form.cardQuestion.toPlainText())
|
|
||||||
a = unicode(self.form.cardAnswer.toPlainText())
|
|
||||||
self.form.cardAnswer.setPlainText(q)
|
|
||||||
self.form.cardQuestion.setPlainText(a)
|
|
||||||
|
|
||||||
def readCard(self):
|
|
||||||
self.updatingCards = True
|
|
||||||
t = self.card.template()
|
|
||||||
f = self.form
|
f = self.form
|
||||||
f.background.setPalette(QPalette(QColor(t['bg'])))
|
fld['font'] = f.fontFamily.currentFont().family()
|
||||||
f.cardQuestion.setPlainText(self.formatToScreen(t['qfmt']))
|
fld['size'] = f.fontSize.value()
|
||||||
f.cardAnswer.setPlainText(self.formatToScreen(t['afmt']))
|
fld['sticky'] = f.sticky.isChecked()
|
||||||
f.questionInAnswer.setChecked(t['hideQ'])
|
fld['rtl'] = f.rtl.isChecked()
|
||||||
f.allowEmptyAnswer.setChecked(t['emptyAns'])
|
|
||||||
f.alignment.setCurrentIndex(t['align'])
|
|
||||||
if t['typeAns'] is None:
|
|
||||||
f.typeAnswer.setCurrentIndex(0)
|
|
||||||
else:
|
|
||||||
f.typeAnswer.setCurrentIndex(t['typeAns'] + 1)
|
|
||||||
# model-level, but there's nowhere else to put this
|
|
||||||
f.clozectx.setChecked(self.model['clozectx'])
|
|
||||||
self.updatingCards = False
|
|
||||||
|
|
||||||
def fillCardList(self):
|
def reject(self):
|
||||||
self.form.cardList.clear()
|
|
||||||
cards = []
|
|
||||||
idx = 0
|
|
||||||
for n, c in enumerate(self.cards):
|
|
||||||
if c.ord == self.ord:
|
|
||||||
cards.append(_("%s (current)") % c.template()['name'])
|
|
||||||
idx = n
|
|
||||||
else:
|
|
||||||
cards.append(c.template()['name'])
|
|
||||||
self.form.cardList.addItems(cards)
|
|
||||||
self.form.cardList.setCurrentIndex(idx)
|
|
||||||
self.cardChanged(idx)
|
|
||||||
self.form.cardList.setFocus()
|
|
||||||
|
|
||||||
def cardChanged(self, idx):
|
|
||||||
self.card = self.cards[idx]
|
|
||||||
self.readCard()
|
|
||||||
self.renderPreview()
|
|
||||||
|
|
||||||
def saveCard(self):
|
|
||||||
if self.updatingCards:
|
|
||||||
return
|
|
||||||
t = self.card.template()
|
|
||||||
t['align'] = self.form.alignment.currentIndex()
|
|
||||||
t['bg'] = unicode(
|
|
||||||
self.form.background.palette().window().color().name())
|
|
||||||
t['hideQ'] = self.form.questionInAnswer.isChecked()
|
|
||||||
t['emptyAns'] = self.form.allowEmptyAnswer.isChecked()
|
|
||||||
idx = self.form.typeAnswer.currentIndex()
|
|
||||||
if not idx:
|
|
||||||
t['typeAns'] = None
|
|
||||||
else:
|
|
||||||
t['typeAns'] = idx-1
|
|
||||||
self.model['clozectx'] = self.form.clozectx.isChecked()
|
|
||||||
self.renderPreview()
|
|
||||||
|
|
||||||
def chooseColour(self, button, type="field"):
|
|
||||||
new = QColorDialog.getColor(button.palette().window().color(), self,
|
|
||||||
_("Choose Color"),
|
|
||||||
QColorDialog.DontUseNativeDialog)
|
|
||||||
if new.isValid():
|
|
||||||
button.setPalette(QPalette(new))
|
|
||||||
if type == "field":
|
|
||||||
self.saveField()
|
self.saveField()
|
||||||
else:
|
self.mm.save(self.model)
|
||||||
self.saveCard()
|
self.mw.reset()
|
||||||
|
QDialog.reject(self)
|
||||||
def renderPreview(self):
|
|
||||||
c = self.card
|
|
||||||
styles = self.model['css']
|
|
||||||
styles += "\n.cloze { font-weight: bold; color: blue; }"
|
|
||||||
self.form.preview.setHtml(
|
|
||||||
('<html><head>%s</head><body class="%s">' %
|
|
||||||
(getBase(self.col), c.cssClass())) +
|
|
||||||
"<style>" + styles + "</style>" +
|
|
||||||
mungeQA(c.q(reload=True)) +
|
|
||||||
self.maybeTextInput() +
|
|
||||||
"<hr>" +
|
|
||||||
mungeQA(c.a())
|
|
||||||
+ "</body></html>")
|
|
||||||
clearAudioQueue()
|
|
||||||
if c.id not in self.playedAudio:
|
|
||||||
playFromText(c.q())
|
|
||||||
playFromText(c.a())
|
|
||||||
self.playedAudio[c.id] = True
|
|
||||||
|
|
||||||
def maybeTextInput(self):
|
|
||||||
if self.card.template()['typeAns'] is not None:
|
|
||||||
return "<center><input type=text></center>"
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
self.reject()
|
self.reject()
|
||||||
|
|
||||||
def reject(self):
|
|
||||||
return QDialog.reject(self)
|
|
||||||
self.mm.save(self.model)
|
|
||||||
saveGeom(self, "CardLayout")
|
|
||||||
saveSplitter(self.form.splitter, "clayout")
|
|
||||||
self.mw.reset()
|
|
||||||
return QDialog.reject(self)
|
|
||||||
|
|
||||||
|
|
||||||
modified = False
|
|
||||||
self.mw.startProgress()
|
|
||||||
self.col.updateProgress(_("Applying changes..."))
|
|
||||||
reset=True
|
|
||||||
if len(self.fieldOrdinalUpdatedIds) > 0:
|
|
||||||
self.col.rebuildFieldOrdinals(self.model.id, self.fieldOrdinalUpdatedIds)
|
|
||||||
modified = True
|
|
||||||
if self.needFieldRebuild:
|
|
||||||
modified = True
|
|
||||||
if modified:
|
|
||||||
self.note.model.setModified()
|
|
||||||
self.col.flushMod()
|
|
||||||
if self.noteedit and self.noteedit.onChange:
|
|
||||||
self.noteedit.onChange("all")
|
|
||||||
reset=False
|
|
||||||
if reset:
|
|
||||||
self.mw.reset()
|
|
||||||
self.col.finishProgress()
|
|
||||||
QDialog.reject(self)
|
|
||||||
|
|
||||||
def onHelp(self):
|
def onHelp(self):
|
||||||
openHelp("CardLayout")
|
openHelp("Fields")
|
||||||
|
|
||||||
# Fields
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
def setupFields(self):
|
|
||||||
self.fieldOrdinalUpdatedIds = []
|
|
||||||
self.updatingFields = False
|
|
||||||
self.needFieldRebuild = False
|
|
||||||
c = self.connect; f = self.form
|
|
||||||
sc = SIGNAL("stateChanged(int)")
|
|
||||||
cl = SIGNAL("clicked()")
|
|
||||||
c(f.fieldAdd, cl, self.addField)
|
|
||||||
c(f.fieldDelete, cl, self.deleteField)
|
|
||||||
c(f.fieldUp, cl, self.moveFieldUp)
|
|
||||||
c(f.fieldDown, cl, self.moveFieldDown)
|
|
||||||
c(f.preserveWhitespace, sc, self.saveField)
|
|
||||||
c(f.fieldUnique, sc, self.saveField)
|
|
||||||
c(f.fieldRequired, sc, self.saveField)
|
|
||||||
c(f.sticky, sc, self.saveField)
|
|
||||||
c(f.fieldList, SIGNAL("currentRowChanged(int)"),
|
|
||||||
self.fieldChanged)
|
|
||||||
c(f.fieldName, SIGNAL("lostFocus()"),
|
|
||||||
self.saveField)
|
|
||||||
c(f.fontFamily, SIGNAL("currentFontChanged(QFont)"),
|
|
||||||
self.saveField)
|
|
||||||
c(f.fontSize, SIGNAL("valueChanged(int)"),
|
|
||||||
self.saveField)
|
|
||||||
c(f.fontSizeEdit, SIGNAL("valueChanged(int)"),
|
|
||||||
self.saveField)
|
|
||||||
w = self.form.fontColour
|
|
||||||
c(w, SIGNAL("clicked()"),
|
|
||||||
lambda w=w: self.chooseColour(w))
|
|
||||||
c(self.form.rtl,
|
|
||||||
SIGNAL("stateChanged(int)"),
|
|
||||||
self.saveField)
|
|
||||||
|
|
||||||
def fieldChanged(self):
|
|
||||||
row = self.form.fieldList.currentRow()
|
|
||||||
if row == -1:
|
|
||||||
row = 0
|
|
||||||
self.field = self.model['flds'][row]
|
|
||||||
self.readField()
|
|
||||||
self.enableFieldMoveButtons()
|
|
||||||
|
|
||||||
def readField(self):
|
|
||||||
fld = self.field
|
|
||||||
f = self.form
|
|
||||||
self.updatingFields = True
|
|
||||||
f.fieldName.setText(fld['name'])
|
|
||||||
f.fieldUnique.setChecked(fld['uniq'])
|
|
||||||
f.fieldRequired.setChecked(fld['req'])
|
|
||||||
f.fontFamily.setCurrentFont(QFont(fld['font']))
|
|
||||||
f.fontSize.setValue(fld['qsize'])
|
|
||||||
f.fontSizeEdit.setValue(fld['esize'])
|
|
||||||
f.fontColour.setPalette(QPalette(QColor(fld['qcol'])))
|
|
||||||
f.rtl.setChecked(fld['rtl'])
|
|
||||||
f.preserveWhitespace.setChecked(fld['pre'])
|
|
||||||
f.sticky.setChecked(fld['sticky'])
|
|
||||||
self.updatingFields = False
|
|
||||||
|
|
||||||
def saveField(self, *args):
|
|
||||||
self.needFieldRebuild = True
|
|
||||||
if self.updatingFields:
|
|
||||||
return
|
|
||||||
self.updatingFields = True
|
|
||||||
fld = self.field
|
|
||||||
# get name; we'll handle it last
|
|
||||||
name = unicode(self.form.fieldName.text())
|
|
||||||
if not name:
|
|
||||||
return
|
|
||||||
fld['uniq'] = self.form.fieldUnique.isChecked()
|
|
||||||
fld['req'] = self.form.fieldRequired.isChecked()
|
|
||||||
fld['font'] = unicode(
|
|
||||||
self.form.fontFamily.currentFont().family())
|
|
||||||
fld['qsize'] = self.form.fontSize.value()
|
|
||||||
fld['esize'] = self.form.fontSizeEdit.value()
|
|
||||||
fld['qcol'] = str(
|
|
||||||
self.form.fontColour.palette().window().color().name())
|
|
||||||
fld['rtl'] = self.form.rtl.isChecked()
|
|
||||||
fld['pre'] = self.form.preserveWhitespace.isChecked()
|
|
||||||
fld['sticky'] = self.form.sticky.isChecked()
|
|
||||||
self.updatingFields = False
|
|
||||||
if fld['name'] != name:
|
|
||||||
self.mm.renameField(self.model, fld, name)
|
|
||||||
# as the field name has changed, we have to regenerate cards
|
|
||||||
self.cards = self.col.previewCards(self.note, self.type)
|
|
||||||
self.cardChanged(0)
|
|
||||||
self.renderPreview()
|
|
||||||
self.fillFieldList()
|
|
||||||
|
|
||||||
def fillFieldList(self, row = None):
|
|
||||||
oldRow = self.form.fieldList.currentRow()
|
|
||||||
if oldRow == -1:
|
|
||||||
oldRow = 0
|
|
||||||
self.form.fieldList.clear()
|
|
||||||
n = 1
|
|
||||||
for field in self.model['flds']:
|
|
||||||
label = field['name']
|
|
||||||
item = QListWidgetItem(label)
|
|
||||||
self.form.fieldList.addItem(item)
|
|
||||||
n += 1
|
|
||||||
count = self.form.fieldList.count()
|
|
||||||
if row != None:
|
|
||||||
self.form.fieldList.setCurrentRow(row)
|
|
||||||
else:
|
|
||||||
while (count > 0 and oldRow > (count - 1)):
|
|
||||||
oldRow -= 1
|
|
||||||
self.form.fieldList.setCurrentRow(oldRow)
|
|
||||||
self.enableFieldMoveButtons()
|
|
||||||
|
|
||||||
def enableFieldMoveButtons(self):
|
|
||||||
row = self.form.fieldList.currentRow()
|
|
||||||
if row < 1:
|
|
||||||
self.form.fieldUp.setEnabled(False)
|
|
||||||
else:
|
|
||||||
self.form.fieldUp.setEnabled(True)
|
|
||||||
if row == -1 or row >= (self.form.fieldList.count() - 1):
|
|
||||||
self.form.fieldDown.setEnabled(False)
|
|
||||||
else:
|
|
||||||
self.form.fieldDown.setEnabled(True)
|
|
||||||
|
|
||||||
def addField(self):
|
|
||||||
f = self.mm.newField(self.model)
|
|
||||||
l = len(self.model['flds'])
|
|
||||||
f['name'] = _("Field %d") % l
|
|
||||||
self.mw.progress.start()
|
|
||||||
self.mm.addField(self.model, f)
|
|
||||||
self.mw.progress.finish()
|
|
||||||
self.reload()
|
|
||||||
self.form.fieldList.setCurrentRow(l)
|
|
||||||
self.form.fieldName.setFocus()
|
|
||||||
self.form.fieldName.selectAll()
|
|
||||||
|
|
||||||
def deleteField(self):
|
|
||||||
row = self.form.fieldList.currentRow()
|
|
||||||
if row == -1:
|
|
||||||
return
|
|
||||||
if len(self.model.fields) < 2:
|
|
||||||
showInfo(_("Please add a new field first."))
|
|
||||||
return
|
|
||||||
if askUser(_("Delete this field and its data from all notes?")):
|
|
||||||
self.mw.progress.start()
|
|
||||||
self.model.delField(self.field)
|
|
||||||
self.mw.progress.finish()
|
|
||||||
# need to update q/a format
|
|
||||||
self.reload()
|
|
||||||
|
|
||||||
def moveFieldUp(self):
|
|
||||||
row = self.form.fieldList.currentRow()
|
|
||||||
if row == -1:
|
|
||||||
return
|
|
||||||
if row == 0:
|
|
||||||
return
|
|
||||||
self.mw.progress.start()
|
|
||||||
self.model.moveField(self.field, row-1)
|
|
||||||
self.mw.progress.finish()
|
|
||||||
self.form.fieldList.setCurrentRow(row-1)
|
|
||||||
self.reload()
|
|
||||||
|
|
||||||
def moveFieldDown(self):
|
|
||||||
row = self.form.fieldList.currentRow()
|
|
||||||
if row == -1:
|
|
||||||
return
|
|
||||||
if row == len(self.model.fields) - 1:
|
|
||||||
return
|
|
||||||
self.mw.progress.start()
|
|
||||||
self.model.moveField(self.field, row+1)
|
|
||||||
self.mw.progress.finish()
|
|
||||||
self.form.fieldList.setCurrentRow(row+1)
|
|
||||||
self.reload()
|
|
||||||
|
|
150
aqt/main.py
150
aqt/main.py
|
@ -193,6 +193,7 @@ Are you sure?"""):
|
||||||
# then load collection and launch into the deck browser
|
# then load collection and launch into the deck browser
|
||||||
print "fixme: safeguard against multiple instances"
|
print "fixme: safeguard against multiple instances"
|
||||||
self.col = Collection(self.pm.collectionPath())
|
self.col = Collection(self.pm.collectionPath())
|
||||||
|
self.progress.setupDB(self.col.db)
|
||||||
# skip the reset step; open overview directly
|
# skip the reset step; open overview directly
|
||||||
self.moveToState("review")
|
self.moveToState("review")
|
||||||
|
|
||||||
|
@ -212,8 +213,6 @@ Are you sure?"""):
|
||||||
getattr(self, "_"+state+"State")(oldState, *args)
|
getattr(self, "_"+state+"State")(oldState, *args)
|
||||||
|
|
||||||
def _deckBrowserState(self, oldState):
|
def _deckBrowserState(self, oldState):
|
||||||
self.disableDeckMenuItems()
|
|
||||||
self.closeAllWindows()
|
|
||||||
self.deckBrowser.show()
|
self.deckBrowser.show()
|
||||||
|
|
||||||
def _colLoadingState(self, oldState):
|
def _colLoadingState(self, oldState):
|
||||||
|
@ -429,27 +428,33 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
|
||||||
else:
|
else:
|
||||||
aw.close()
|
aw.close()
|
||||||
|
|
||||||
def close(self, showBrowser=True):
|
def close(self):
|
||||||
"Close current deck."
|
"Close and backup collection."
|
||||||
if not self.col:
|
if not self.col:
|
||||||
return
|
return
|
||||||
# if we were cramming, restore the standard scheduler
|
|
||||||
if self.col.stdSched():
|
|
||||||
self.col.reset()
|
|
||||||
runHook("deckClosing")
|
runHook("deckClosing")
|
||||||
print "focusOut() should be handled with deckClosing now"
|
#self.col.close()
|
||||||
|
self.backup()
|
||||||
self.closeAllWindows()
|
self.closeAllWindows()
|
||||||
self.col.close()
|
self.col.close()
|
||||||
self.col = None
|
self.col = None
|
||||||
if showBrowser:
|
|
||||||
self.moveToState("deckBrowser")
|
# Syncing
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
def backup(self):
|
||||||
|
print "backup"
|
||||||
|
|
||||||
# Syncing
|
# Syncing
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def onSync(self):
|
def onSync(self):
|
||||||
return
|
from aqt.sync import Syncer
|
||||||
return showInfo("sync not yet implemented")
|
# close collection if loaded
|
||||||
|
if self.col:
|
||||||
|
self.col.close()
|
||||||
|
#
|
||||||
|
Syncer()
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
@ -484,11 +489,7 @@ Debug info:\n%s""") % traceback.format_exc(), help="DeckErrors")
|
||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
"User hit the X button, etc."
|
"User hit the X button, etc."
|
||||||
print "fixme: exit from edit current, review, etc"
|
self.close()
|
||||||
if self.state == "editCurrentNote":
|
|
||||||
event.ignore()
|
|
||||||
return self.moveToState("saveEdit")
|
|
||||||
self.close(showBrowser=False)
|
|
||||||
# if self.pm.profile['syncOnProgramOpen']:
|
# if self.pm.profile['syncOnProgramOpen']:
|
||||||
# self.showBrowser = False
|
# self.showBrowser = False
|
||||||
# self.syncDeck(interactive=False)
|
# self.syncDeck(interactive=False)
|
||||||
|
@ -857,118 +858,9 @@ Please choose a new deck name:"""))
|
||||||
|
|
||||||
def onSchemaMod(self, arg):
|
def onSchemaMod(self, arg):
|
||||||
return askUser(_("""\
|
return askUser(_("""\
|
||||||
This operation can't be merged when syncing, so the next \
|
This operation can't be merged when syncing, so if you have made \
|
||||||
sync will overwrite any changes made on other devices that \
|
changes on other devices that haven't been synced to this device yet, \
|
||||||
haven't been synced here yet. Continue?"""))
|
they will be lost. Are you sure you want to continue?"""))
|
||||||
|
|
||||||
# Media locations
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
# def setupMedia(self, deck):
|
|
||||||
# print "setup media"
|
|
||||||
# return
|
|
||||||
# prefix = self.pm.profile['mediaLocation']
|
|
||||||
# prev = deck.getVar("mediaLocation") or ""
|
|
||||||
# # set the media prefix
|
|
||||||
# if not prefix:
|
|
||||||
# next = ""
|
|
||||||
# elif prefix == "dropbox":
|
|
||||||
# p = self.dropboxFolder()
|
|
||||||
# next = os.path.join(p, "Public", "Anki")
|
|
||||||
# else:
|
|
||||||
# next = prefix
|
|
||||||
# # check if the media has moved
|
|
||||||
# migrateFrom = None
|
|
||||||
# if prev != next:
|
|
||||||
# # check if they were using plugin
|
|
||||||
# if not prev:
|
|
||||||
# p = self.dropboxFolder()
|
|
||||||
# p = os.path.join(p, "Public")
|
|
||||||
# deck.mediaPrefix = p
|
|
||||||
# migrateFrom = deck.mediaDir()
|
|
||||||
# if not migrateFrom:
|
|
||||||
# # find the old location
|
|
||||||
# deck.mediaPrefix = prev
|
|
||||||
# dir = deck.mediaDir()
|
|
||||||
# if dir and os.listdir(dir):
|
|
||||||
# # it contains files; we'll need to migrate
|
|
||||||
# migrateFrom = dir
|
|
||||||
# # setup new folder
|
|
||||||
# deck.mediaPrefix = next
|
|
||||||
# if migrateFrom:
|
|
||||||
# # force creation of new folder
|
|
||||||
# dir = deck.mediaDir(create=True)
|
|
||||||
# # migrate old files
|
|
||||||
# self.migrateMedia(migrateFrom, dir)
|
|
||||||
# else:
|
|
||||||
# # chdir if dir exists
|
|
||||||
# dir = deck.mediaDir()
|
|
||||||
# # update location
|
|
||||||
# deck.setVar("mediaLocation", next, mod=False)
|
|
||||||
# if dir and prefix == "dropbox":
|
|
||||||
# self.setupDropbox(deck)
|
|
||||||
|
|
||||||
# def migrateMedia(self, from_, to):
|
|
||||||
# if from_ == to:
|
|
||||||
# return
|
|
||||||
# files = os.listdir(from_)
|
|
||||||
# skipped = False
|
|
||||||
# for f in files:
|
|
||||||
# src = os.path.join(from_, f)
|
|
||||||
# dst = os.path.join(to, f)
|
|
||||||
# if not os.path.isfile(src):
|
|
||||||
# skipped = True
|
|
||||||
# continue
|
|
||||||
# if not os.path.exists(dst):
|
|
||||||
# shutil.copy2(src, dst)
|
|
||||||
# if not skipped:
|
|
||||||
# # everything copied, we can remove old folder
|
|
||||||
# shutil.rmtree(from_, ignore_errors=True)
|
|
||||||
|
|
||||||
# def dropboxFolder(self):
|
|
||||||
# try:
|
|
||||||
# import aqt.dropbox as db
|
|
||||||
# p = db.getPath()
|
|
||||||
# except:
|
|
||||||
# if isWin:
|
|
||||||
# s = QSettings(QSettings.UserScope, "Microsoft", "Windows")
|
|
||||||
# s.beginGroup("CurrentVersion/Explorer/Shell Folders")
|
|
||||||
# p = os.path.join(s.value("Personal"), "My Dropbox")
|
|
||||||
# else:
|
|
||||||
# p = os.path.expanduser("~/Dropbox")
|
|
||||||
# return p
|
|
||||||
|
|
||||||
# def setupDropbox(self, deck):
|
|
||||||
# if not self.pm.profile['dropboxPublicFolder']:
|
|
||||||
# # put a file in the folder
|
|
||||||
# open(os.path.join(
|
|
||||||
# deck.mediaPrefix, "right-click-me.txt"), "w").write("")
|
|
||||||
# # tell user what to do
|
|
||||||
# showInfo(_("""\
|
|
||||||
# A file called right-click-me.txt has been placed in DropBox's public folder. \
|
|
||||||
# After clicking OK, this folder will appear. Please right click on the file (\
|
|
||||||
# command+click on a Mac), choose DropBox>Copy Public Link, and paste the \
|
|
||||||
# link into Anki."""))
|
|
||||||
# # open folder and text prompt
|
|
||||||
# self.onOpenPluginFolder(deck.mediaPrefix)
|
|
||||||
# txt = getText(_("Paste path here:"), parent=self)
|
|
||||||
# if txt[0]:
|
|
||||||
# fail = False
|
|
||||||
# if not txt[0].lower().startswith("http"):
|
|
||||||
# fail = True
|
|
||||||
# if not txt[0].lower().endswith("right-click-me.txt"):
|
|
||||||
# fail = True
|
|
||||||
# if fail:
|
|
||||||
# showInfo(_("""\
|
|
||||||
# That doesn't appear to be a public link. You'll be asked again when the deck \
|
|
||||||
# is next loaded."""))
|
|
||||||
# else:
|
|
||||||
# self.pm.profile['dropboxPublicFolder'] = os.path.dirname(txt[0])
|
|
||||||
# if self.pm.profile['dropboxPublicFolder']:
|
|
||||||
# # update media url
|
|
||||||
# deck.setVar(
|
|
||||||
# "mediaURL", self.pm.profile['dropboxPublicFolder'] + "/" +
|
|
||||||
# os.path.basename(deck.mediaDir()) + "/")
|
|
||||||
|
|
||||||
# Advanced features
|
# Advanced features
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
|
@ -25,10 +25,10 @@ class ProgressManager(object):
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def setupDB(self, db):
|
def setupDB(self, db):
|
||||||
"Install a handler in the current deck."
|
"Install a handler in the current DB."
|
||||||
self.lastDbProgress = 0
|
self.lastDbProgress = 0
|
||||||
self.inDB = False
|
self.inDB = False
|
||||||
db.set_progress_handler(self._dbProgress, 100000)
|
db.set_progress_handler(self._dbProgress, 10000)
|
||||||
|
|
||||||
def _dbProgress(self):
|
def _dbProgress(self):
|
||||||
"Called from SQLite."
|
"Called from SQLite."
|
||||||
|
|
|
@ -5,15 +5,14 @@ from aqt.qt import *
|
||||||
import os, types, socket, time, traceback
|
import os, types, socket, time, traceback
|
||||||
import aqt
|
import aqt
|
||||||
import anki
|
import anki
|
||||||
from anki.sync import SyncClient, HttpSyncServerProxy, copyLocalMedia
|
#from anki.sync import SyncClient, HttpSyncServerProxy, copyLocalMedia from
|
||||||
from anki.sync import SYNC_HOST, SYNC_PORT
|
#anki.sync import SYNC_HOST, SYNC_PORT
|
||||||
from anki.errors import *
|
from anki.errors import *
|
||||||
from anki import Deck
|
|
||||||
from anki.db import sqlite
|
from anki.db import sqlite
|
||||||
import aqt.forms
|
import aqt.forms
|
||||||
from anki.hooks import addHook, removeHook
|
from anki.hooks import addHook, removeHook
|
||||||
|
|
||||||
class SyncManager(object):
|
class Syncer(object):
|
||||||
|
|
||||||
# Syncing
|
# Syncing
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
|
@ -6,13 +6,16 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>403</width>
|
<width>412</width>
|
||||||
<height>352</height>
|
<height>352</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Fields</string>
|
<string>Fields</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
@ -37,62 +40,28 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="fieldAdd">
|
<widget class="QPushButton" name="fieldAdd">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>Add</string>
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="icons.qrc">
|
|
||||||
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="fieldDelete">
|
<widget class="QPushButton" name="fieldDelete">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>Delete</string>
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="icons.qrc">
|
|
||||||
<normaloff>:/icons/editdelete.png</normaloff>:/icons/editdelete.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="fieldUp">
|
<widget class="QPushButton" name="fieldRename">
|
||||||
<property name="toolTip">
|
|
||||||
<string>Move selected field up</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>Rename</string>
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="icons.qrc">
|
|
||||||
<normaloff>:/icons/arrow-up.png</normaloff>:/icons/arrow-up.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="fieldDown">
|
<widget class="QPushButton" name="fieldPosition">
|
||||||
<property name="toolTip">
|
|
||||||
<string>Move selected field down</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>Reposition</string>
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="icons.qrc">
|
|
||||||
<normaloff>:/icons/arrow-down.png</normaloff>:/icons/arrow-down.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -115,27 +84,14 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="_2">
|
<layout class="QGridLayout" name="_2">
|
||||||
<item row="0" column="1" colspan="2">
|
|
||||||
<widget class="QLineEdit" name="fieldName"/>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label_20">
|
|
||||||
<property name="text">
|
|
||||||
<string>Name</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Editing Font</string>
|
<string>Editing Font</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QFontComboBox" name="fontFamily">
|
<widget class="QFontComboBox" name="fontFamily">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
|
@ -145,14 +101,14 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QCheckBox" name="rtl">
|
<widget class="QCheckBox" name="rtl">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Reverse text direction (RTL)</string>
|
<string>Reverse text direction (RTL)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="QSpinBox" name="fontSize">
|
<widget class="QSpinBox" name="fontSize">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
|
@ -162,21 +118,21 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QCheckBox" name="sticky">
|
<widget class="QCheckBox" name="sticky">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Remember last input</string>
|
<string>Remember last input when adding</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_18">
|
<widget class="QLabel" name="label_18">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Options</string>
|
<string>Options</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QRadioButton" name="sortField">
|
<widget class="QRadioButton" name="sortField">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Sort by this field in the browser</string>
|
<string>Sort by this field in the browser</string>
|
||||||
|
@ -201,11 +157,11 @@
|
||||||
<tabstop>fieldList</tabstop>
|
<tabstop>fieldList</tabstop>
|
||||||
<tabstop>fieldAdd</tabstop>
|
<tabstop>fieldAdd</tabstop>
|
||||||
<tabstop>fieldDelete</tabstop>
|
<tabstop>fieldDelete</tabstop>
|
||||||
<tabstop>fieldUp</tabstop>
|
<tabstop>fieldRename</tabstop>
|
||||||
<tabstop>fieldDown</tabstop>
|
<tabstop>fieldPosition</tabstop>
|
||||||
<tabstop>fieldName</tabstop>
|
|
||||||
<tabstop>fontFamily</tabstop>
|
<tabstop>fontFamily</tabstop>
|
||||||
<tabstop>fontSize</tabstop>
|
<tabstop>fontSize</tabstop>
|
||||||
|
<tabstop>sortField</tabstop>
|
||||||
<tabstop>sticky</tabstop>
|
<tabstop>sticky</tabstop>
|
||||||
<tabstop>rtl</tabstop>
|
<tabstop>rtl</tabstop>
|
||||||
<tabstop>buttonBox</tabstop>
|
<tabstop>buttonBox</tabstop>
|
||||||
|
|
Loading…
Reference in a new issue