start reworking card layout screen
- front/back/css shown in tabs - front/back preview switchable; only one webview needs to be loaded - dropdown to select cloze number in preview - search box to search in front/back/css
This commit is contained in:
parent
f23eb350e4
commit
5167bb57be
@ -4,7 +4,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import re
|
|
||||||
import time
|
import time
|
||||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
|
@ -809,7 +809,12 @@ class RustBackend:
|
|||||||
self._run_command(pb.BackendInput(set_preferences=prefs))
|
self._run_command(pb.BackendInput(set_preferences=prefs))
|
||||||
|
|
||||||
def cloze_numbers_in_note(self, note: pb.Note) -> List[int]:
|
def cloze_numbers_in_note(self, note: pb.Note) -> List[int]:
|
||||||
return list(self._run_command(pb.BackendInput(cloze_numbers_in_note=note)).cloze_numbers_in_note.numbers)
|
return list(
|
||||||
|
self._run_command(
|
||||||
|
pb.BackendInput(cloze_numbers_in_note=note)
|
||||||
|
).cloze_numbers_in_note.numbers
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def translate_string_in(
|
def translate_string_in(
|
||||||
key: TR, **kwargs: Union[str, int, float]
|
key: TR, **kwargs: Union[str, int, float]
|
||||||
|
@ -34,7 +34,6 @@ from typing import Any, Dict, List, Optional, Tuple
|
|||||||
import anki
|
import anki
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.cards import Card
|
from anki.cards import Card
|
||||||
from anki.decks import DeckManager
|
|
||||||
from anki.models import NoteType
|
from anki.models import NoteType
|
||||||
from anki.notes import Note
|
from anki.notes import Note
|
||||||
from anki.rsbackend import PartiallyRenderedCard, TemplateReplacementList
|
from anki.rsbackend import PartiallyRenderedCard, TemplateReplacementList
|
||||||
@ -57,9 +56,11 @@ class TemplateRenderContext:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_card_layout(
|
def from_card_layout(
|
||||||
cls, note: Note, card: Card, template: Dict
|
cls, note: Note, card: Card, notetype: NoteType, template: Dict
|
||||||
) -> TemplateRenderContext:
|
) -> TemplateRenderContext:
|
||||||
return TemplateRenderContext(note.col, card, note, template=template)
|
return TemplateRenderContext(
|
||||||
|
note.col, card, note, notetype=notetype, template=template
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -67,6 +68,7 @@ class TemplateRenderContext:
|
|||||||
card: Card,
|
card: Card,
|
||||||
note: Note,
|
note: Note,
|
||||||
browser: bool = False,
|
browser: bool = False,
|
||||||
|
notetype: NoteType = None,
|
||||||
template: Optional[Dict] = None,
|
template: Optional[Dict] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._col = col.weakref()
|
self._col = col.weakref()
|
||||||
@ -74,7 +76,10 @@ class TemplateRenderContext:
|
|||||||
self._note = note
|
self._note = note
|
||||||
self._browser = browser
|
self._browser = browser
|
||||||
self._template = template
|
self._template = template
|
||||||
self._note_type = note.model()
|
if not notetype:
|
||||||
|
self._note_type = note.model()
|
||||||
|
else:
|
||||||
|
self._note_type = notetype
|
||||||
|
|
||||||
# if you need to store extra state to share amongst rendering
|
# if you need to store extra state to share amongst rendering
|
||||||
# hooks, you can insert it into this dictionary
|
# hooks, you can insert it into this dictionary
|
||||||
@ -85,7 +90,8 @@ class TemplateRenderContext:
|
|||||||
|
|
||||||
# legacy
|
# legacy
|
||||||
def fields(self) -> Dict[str, str]:
|
def fields(self) -> Dict[str, str]:
|
||||||
return fields_for_rendering(self.col(), self.card(), self.note())
|
print(".fields() is obsolote, use .note().items()")
|
||||||
|
return dict(self._note.items())
|
||||||
|
|
||||||
def card(self) -> Card:
|
def card(self) -> Card:
|
||||||
"""Returns the card being rendered.
|
"""Returns the card being rendered.
|
||||||
@ -177,26 +183,6 @@ def templates_for_card(card: Card, browser: bool) -> Tuple[str, str]:
|
|||||||
return q, a # type: ignore
|
return q, a # type: ignore
|
||||||
|
|
||||||
|
|
||||||
# legacy
|
|
||||||
def fields_for_rendering(
|
|
||||||
col: anki.storage._Collection, card: Card, note: Note
|
|
||||||
) -> Dict[str, str]:
|
|
||||||
# fields from note
|
|
||||||
fields = dict(note.items())
|
|
||||||
|
|
||||||
# add special fields
|
|
||||||
fields["Tags"] = note.stringTags().strip()
|
|
||||||
fields["Type"] = card.note_type()["name"]
|
|
||||||
fields["Deck"] = col.decks.name(card.odid or card.did)
|
|
||||||
fields["Subdeck"] = DeckManager.basename(fields["Deck"])
|
|
||||||
fields["Card"] = card.template()["name"]
|
|
||||||
flag = card.userFlag()
|
|
||||||
fields["CardFlag"] = flag and f"flag{flag}" or ""
|
|
||||||
fields["c%d" % (card.ord + 1)] = "1"
|
|
||||||
|
|
||||||
return fields
|
|
||||||
|
|
||||||
|
|
||||||
def apply_custom_filters(
|
def apply_custom_filters(
|
||||||
rendered: TemplateReplacementList,
|
rendered: TemplateReplacementList,
|
||||||
ctx: TemplateRenderContext,
|
ctx: TemplateRenderContext,
|
||||||
@ -226,7 +212,7 @@ def apply_custom_filters(
|
|||||||
"fmod_" + filter_name,
|
"fmod_" + filter_name,
|
||||||
field_text,
|
field_text,
|
||||||
"",
|
"",
|
||||||
ctx.fields(),
|
ctx.note().items(),
|
||||||
node.field_name,
|
node.field_name,
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from anki.consts import MODEL_CLOZE
|
from anki.consts import MODEL_CLOZE
|
||||||
from anki.utils import isWin, joinFields, stripHTML
|
from anki.utils import isWin, stripHTML
|
||||||
from tests.shared import getEmptyCol
|
from tests.shared import getEmptyCol
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
# Copyright: Ankitects Pty Ltd and contributors
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
import copy
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
@ -13,7 +14,7 @@ from anki.lang import _, ngettext
|
|||||||
from anki.notes import Note
|
from anki.notes import Note
|
||||||
from anki.rsbackend import TemplateError
|
from anki.rsbackend import TemplateError
|
||||||
from anki.template import TemplateRenderContext
|
from anki.template import TemplateRenderContext
|
||||||
from anki.utils import isMac, isWin, joinFields
|
from anki.utils import isMac, isWin
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.sound import av_player, play_clicked_audio
|
from aqt.sound import av_player, play_clicked_audio
|
||||||
@ -36,6 +37,7 @@ from aqt.webview import AnkiWebView
|
|||||||
# fixme: card count when removing
|
# fixme: card count when removing
|
||||||
# fixme: i18n
|
# fixme: i18n
|
||||||
# fixme: change tracking and tooltip in fields
|
# fixme: change tracking and tooltip in fields
|
||||||
|
# fixme: replay suppression
|
||||||
|
|
||||||
|
|
||||||
class CardLayout(QDialog):
|
class CardLayout(QDialog):
|
||||||
@ -77,7 +79,6 @@ class CardLayout(QDialog):
|
|||||||
def redraw_everything(self):
|
def redraw_everything(self):
|
||||||
self.ignore_change_signals = True
|
self.ignore_change_signals = True
|
||||||
self.updateTopArea()
|
self.updateTopArea()
|
||||||
self.updateMainArea()
|
|
||||||
self.ignore_change_signals = False
|
self.ignore_change_signals = False
|
||||||
self.update_current_ordinal_and_redraw(self.ord)
|
self.update_current_ordinal_and_redraw(self.ord)
|
||||||
|
|
||||||
@ -184,41 +185,98 @@ class CardLayout(QDialog):
|
|||||||
# template area
|
# template area
|
||||||
tform = self.tform = aqt.forms.template.Ui_Form()
|
tform = self.tform = aqt.forms.template.Ui_Form()
|
||||||
tform.setupUi(left)
|
tform.setupUi(left)
|
||||||
tform.label1.setText(" →")
|
# tform.groupBox_3.setTitle(_("Styling (shared between cards)"))
|
||||||
tform.label2.setText(" →")
|
|
||||||
tform.labelc1.setText(" ↗")
|
|
||||||
tform.labelc2.setText(" ↘")
|
|
||||||
if self.style().objectName() == "gtk+":
|
|
||||||
# gtk+ requires margins in inner layout
|
|
||||||
tform.tlayout1.setContentsMargins(0, 11, 0, 0)
|
|
||||||
tform.tlayout2.setContentsMargins(0, 11, 0, 0)
|
|
||||||
tform.tlayout3.setContentsMargins(0, 11, 0, 0)
|
|
||||||
tform.groupBox_3.setTitle(_("Styling (shared between cards)"))
|
|
||||||
qconnect(tform.front.textChanged, self.write_edits_to_template_and_redraw)
|
qconnect(tform.front.textChanged, self.write_edits_to_template_and_redraw)
|
||||||
qconnect(tform.css.textChanged, self.write_edits_to_template_and_redraw)
|
qconnect(tform.css.textChanged, self.write_edits_to_template_and_redraw)
|
||||||
qconnect(tform.back.textChanged, self.write_edits_to_template_and_redraw)
|
qconnect(tform.back.textChanged, self.write_edits_to_template_and_redraw)
|
||||||
|
qconnect(tform.tabWidget.currentChanged, self.on_editor_changed)
|
||||||
l.addWidget(left, 5)
|
l.addWidget(left, 5)
|
||||||
|
self.search_box = search = QLineEdit()
|
||||||
|
search.setPlaceholderText("Search")
|
||||||
|
qconnect(search.textChanged, self.on_search_changed)
|
||||||
|
qconnect(search.returnPressed, self.on_search_next)
|
||||||
|
tform.tabWidget.setCornerWidget(search)
|
||||||
# preview area
|
# preview area
|
||||||
right = QWidget()
|
right = QWidget()
|
||||||
self.pform: Any = aqt.forms.preview.Ui_Form()
|
self.pform: Any = aqt.forms.preview.Ui_Form()
|
||||||
pform = self.pform
|
pform = self.pform
|
||||||
pform.setupUi(right)
|
pform.setupUi(right)
|
||||||
if self.style().objectName() == "gtk+":
|
|
||||||
# gtk+ requires margins in inner layout
|
if self._isCloze():
|
||||||
pform.frontPrevBox.setContentsMargins(0, 11, 0, 0)
|
nums = self.note.cloze_numbers_in_fields()
|
||||||
pform.backPrevBox.setContentsMargins(0, 11, 0, 0)
|
if self.ord + 1 not in nums:
|
||||||
|
# current card is empty
|
||||||
|
nums.append(self.ord + 1)
|
||||||
|
self.cloze_numbers = sorted(nums)
|
||||||
|
self.setup_cloze_number_box()
|
||||||
|
else:
|
||||||
|
self.cloze_numbers = []
|
||||||
|
self.pform.cloze_number_combo.setHidden(True)
|
||||||
|
|
||||||
self.setupWebviews()
|
self.setupWebviews()
|
||||||
|
|
||||||
l.addWidget(right, 5)
|
l.addWidget(right, 5)
|
||||||
w.setLayout(l)
|
w.setLayout(l)
|
||||||
|
|
||||||
|
def setup_cloze_number_box(self):
|
||||||
|
names = (_("Cloze %d") % n for n in self.cloze_numbers)
|
||||||
|
self.pform.cloze_number_combo.addItems(names)
|
||||||
|
try:
|
||||||
|
idx = self.cloze_numbers.index(self.ord + 1)
|
||||||
|
self.pform.cloze_number_combo.setCurrentIndex(idx)
|
||||||
|
except ValueError:
|
||||||
|
# invalid cloze
|
||||||
|
pass
|
||||||
|
qconnect(
|
||||||
|
self.pform.cloze_number_combo.currentIndexChanged, self.on_change_cloze
|
||||||
|
)
|
||||||
|
|
||||||
|
def current_editor(self) -> QTextEdit:
|
||||||
|
idx = self.tform.tabWidget.currentIndex()
|
||||||
|
if idx == 0:
|
||||||
|
return self.tform.front
|
||||||
|
elif idx == 1:
|
||||||
|
return self.tform.back
|
||||||
|
else:
|
||||||
|
return self.tform.css
|
||||||
|
|
||||||
|
def on_change_cloze(self, idx: int) -> None:
|
||||||
|
self.ord = self.cloze_numbers[idx] - 1
|
||||||
|
self._renderPreview()
|
||||||
|
|
||||||
|
def on_editor_changed(self, idx: int) -> None:
|
||||||
|
if idx == 0:
|
||||||
|
self.pform.preview_front.setChecked(True)
|
||||||
|
elif idx == 1:
|
||||||
|
self.pform.preview_back.setChecked(True)
|
||||||
|
|
||||||
|
def on_search_changed(self, text: str):
|
||||||
|
editor = self.current_editor()
|
||||||
|
if not editor.find(text):
|
||||||
|
# try again from top
|
||||||
|
cursor = editor.textCursor()
|
||||||
|
cursor.movePosition(QTextCursor.Start)
|
||||||
|
editor.setTextCursor(cursor)
|
||||||
|
editor.find(text)
|
||||||
|
|
||||||
|
def on_search_next(self):
|
||||||
|
self.on_search_changed(self.search_box.text())
|
||||||
|
|
||||||
def setupWebviews(self):
|
def setupWebviews(self):
|
||||||
|
if theme_manager.night_mode and not theme_manager.macos_dark_mode():
|
||||||
|
# the grouping box renders incorrectly in the fusion theme. 5.9+
|
||||||
|
# 5.13 behave differently to 5.14, but it looks bad in either case,
|
||||||
|
# and adjusting the top margin makes the 'save PDF' button show in
|
||||||
|
# the wrong place, so for now we just disable the border instead
|
||||||
|
self.setStyleSheet("QGroupBox { border: 0; }")
|
||||||
|
|
||||||
pform = self.pform
|
pform = self.pform
|
||||||
pform.frontWeb = AnkiWebView(title="card layout front")
|
pform.frontWeb = AnkiWebView(title="card layout")
|
||||||
pform.frontPrevBox.addWidget(pform.frontWeb)
|
pform.verticalLayout.addWidget(pform.frontWeb)
|
||||||
pform.backWeb = AnkiWebView(title="card layout back")
|
pform.verticalLayout.setStretch(1, 99)
|
||||||
pform.backPrevBox.addWidget(pform.backWeb)
|
pform.preview_front.isChecked()
|
||||||
|
qconnect(pform.preview_front.toggled, self.on_preview_toggled)
|
||||||
|
qconnect(pform.preview_back.toggled, self.on_preview_toggled)
|
||||||
jsinc = [
|
jsinc = [
|
||||||
"jquery.js",
|
"jquery.js",
|
||||||
"browsersel.js",
|
"browsersel.js",
|
||||||
@ -229,27 +287,24 @@ class CardLayout(QDialog):
|
|||||||
pform.frontWeb.stdHtml(
|
pform.frontWeb.stdHtml(
|
||||||
self.mw.reviewer.revHtml(), css=["reviewer.css"], js=jsinc, context=self,
|
self.mw.reviewer.revHtml(), css=["reviewer.css"], js=jsinc, context=self,
|
||||||
)
|
)
|
||||||
pform.backWeb.stdHtml(
|
|
||||||
self.mw.reviewer.revHtml(), css=["reviewer.css"], js=jsinc, context=self,
|
|
||||||
)
|
|
||||||
pform.frontWeb.set_bridge_command(self._on_bridge_cmd, self)
|
pform.frontWeb.set_bridge_command(self._on_bridge_cmd, self)
|
||||||
pform.backWeb.set_bridge_command(self._on_bridge_cmd, self)
|
|
||||||
|
def on_preview_toggled(self):
|
||||||
|
self._renderPreview()
|
||||||
|
|
||||||
def _on_bridge_cmd(self, cmd: str) -> Any:
|
def _on_bridge_cmd(self, cmd: str) -> Any:
|
||||||
if cmd.startswith("play:"):
|
if cmd.startswith("play:"):
|
||||||
play_clicked_audio(cmd, self.rendered_card)
|
play_clicked_audio(cmd, self.rendered_card)
|
||||||
|
|
||||||
def updateMainArea(self):
|
|
||||||
if self._isCloze():
|
|
||||||
cnt = len(self.note.cloze_numbers_in_fields())
|
|
||||||
for g in self.pform.groupBox, self.pform.groupBox_2:
|
|
||||||
g.setTitle(g.title() + _(" (1 of %d)") % max(cnt, 1))
|
|
||||||
|
|
||||||
def ephemeral_card_for_rendering(self) -> Card:
|
def ephemeral_card_for_rendering(self) -> Card:
|
||||||
card = Card(self.col)
|
card = Card(self.col)
|
||||||
card.ord = self.ord
|
card.ord = self.ord
|
||||||
|
template = copy.copy(self.current_template())
|
||||||
|
# may differ in cloze case
|
||||||
|
template["ord"] = card.ord
|
||||||
|
# this fetches notetype, we should pass it in
|
||||||
output = TemplateRenderContext.from_card_layout(
|
output = TemplateRenderContext.from_card_layout(
|
||||||
self.note, card, template=self.current_template()
|
self.note, card, notetype=self.model, template=template
|
||||||
).render()
|
).render()
|
||||||
card.set_render_output(output)
|
card.set_render_output(output)
|
||||||
return card
|
return card
|
||||||
@ -288,6 +343,8 @@ class CardLayout(QDialog):
|
|||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def current_template(self) -> Dict:
|
def current_template(self) -> Dict:
|
||||||
|
if self._isCloze():
|
||||||
|
return self.templates[0]
|
||||||
return self.templates[self.ord]
|
return self.templates[self.ord]
|
||||||
|
|
||||||
def fill_fields_from_template(self):
|
def fill_fields_from_template(self):
|
||||||
@ -344,18 +401,24 @@ class CardLayout(QDialog):
|
|||||||
|
|
||||||
bodyclass = theme_manager.body_classes_for_card_ord(c.ord)
|
bodyclass = theme_manager.body_classes_for_card_ord(c.ord)
|
||||||
|
|
||||||
q = ti(self.mw.prepare_card_text_for_display(c.q()))
|
if self.pform.preview_front.isChecked():
|
||||||
q = gui_hooks.card_will_show(q, c, "clayoutQuestion")
|
q = ti(self.mw.prepare_card_text_for_display(c.q()))
|
||||||
|
q = gui_hooks.card_will_show(q, c, "clayoutQuestion")
|
||||||
a = ti(self.mw.prepare_card_text_for_display(c.a()), type="a")
|
text = q
|
||||||
a = gui_hooks.card_will_show(a, c, "clayoutAnswer")
|
audio = c.question_av_tags()
|
||||||
|
else:
|
||||||
|
a = ti(self.mw.prepare_card_text_for_display(c.a()), type="a")
|
||||||
|
a = gui_hooks.card_will_show(a, c, "clayoutAnswer")
|
||||||
|
text = a
|
||||||
|
audio = c.answer_av_tags()
|
||||||
|
|
||||||
# use _showAnswer to avoid the longer delay
|
# use _showAnswer to avoid the longer delay
|
||||||
self.pform.frontWeb.eval("_showAnswer(%s,'%s');" % (json.dumps(q), bodyclass))
|
self.pform.frontWeb.eval(
|
||||||
self.pform.backWeb.eval("_showAnswer(%s, '%s');" % (json.dumps(a), bodyclass))
|
"_showAnswer(%s,'%s');" % (json.dumps(text), bodyclass)
|
||||||
|
)
|
||||||
|
|
||||||
if c.id not in self.playedAudio:
|
if c.id not in self.playedAudio:
|
||||||
av_player.play_tags(c.question_av_tags() + c.answer_av_tags())
|
av_player.play_tags(audio)
|
||||||
self.playedAudio[c.id] = True
|
self.playedAudio[c.id] = True
|
||||||
|
|
||||||
self.updateCardNames()
|
self.updateCardNames()
|
||||||
@ -655,7 +718,6 @@ Enter deck to place new %s cards in, or leave blank:"""
|
|||||||
av_player.stop_and_clear_queue()
|
av_player.stop_and_clear_queue()
|
||||||
saveGeom(self, "CardLayout")
|
saveGeom(self, "CardLayout")
|
||||||
self.pform.frontWeb = None
|
self.pform.frontWeb = None
|
||||||
self.pform.backWeb = None
|
|
||||||
self.model = None
|
self.model = None
|
||||||
self.rendered_card = None
|
self.rendered_card = None
|
||||||
self.mw = None
|
self.mw = None
|
||||||
|
@ -6,40 +6,76 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>335</width>
|
<width>717</width>
|
||||||
<height>282</height>
|
<height>636</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string notr="true">Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<property name="margin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="title">
|
<item>
|
||||||
<string>Front Preview</string>
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
</property>
|
<property name="sizeConstraint">
|
||||||
<layout class="QVBoxLayout" name="frontPrevBox">
|
<enum>QLayout::SetMinimumSize</enum>
|
||||||
<property name="margin">
|
</property>
|
||||||
<number>0</number>
|
<item>
|
||||||
</property>
|
<widget class="QGroupBox" name="front_back_box">
|
||||||
</layout>
|
<property name="title">
|
||||||
</widget>
|
<string/>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="flat">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<bool>true</bool>
|
||||||
<property name="title">
|
</property>
|
||||||
<string>Back Preview</string>
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
</property>
|
<property name="sizeConstraint">
|
||||||
<layout class="QVBoxLayout" name="backPrevBox">
|
<enum>QLayout::SetMinimumSize</enum>
|
||||||
<property name="margin">
|
</property>
|
||||||
<number>0</number>
|
<item>
|
||||||
</property>
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
</layout>
|
<item>
|
||||||
</widget>
|
<widget class="QRadioButton" name="preview_front">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">FRONT</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="preview_back">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">BACK</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="cloze_number_combo"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>470</width>
|
<width>525</width>
|
||||||
<height>569</height>
|
<height>721</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -19,173 +19,62 @@
|
|||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="spacing">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<widget class="QLabel" name="changes_affect_label">
|
||||||
<property name="spacing">
|
<property name="text">
|
||||||
<number>0</number>
|
<string notr="true">CHANGES_WILL_AFFECT</string>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
</widget>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Front Template</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="tlayout1">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QTextEdit" name="front"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label1">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="spacing">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<widget class="QWidget" name="tab">
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
<attribute name="title">
|
||||||
<property name="title">
|
<string notr="true">FRONT</string>
|
||||||
<string>Styling</string>
|
</attribute>
|
||||||
</property>
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<layout class="QVBoxLayout" name="tlayout2">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QTextEdit" name="css"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<widget class="QTextEdit" name="front"/>
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Preferred</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>1</width>
|
|
||||||
<height>15</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labelc1">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>1</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labelc2">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Preferred</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>1</width>
|
|
||||||
<height>10</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</widget>
|
||||||
</layout>
|
<widget class="QWidget" name="tab_2">
|
||||||
</item>
|
<attribute name="title">
|
||||||
<item>
|
<string notr="true">BACK</string>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
</attribute>
|
||||||
<property name="spacing">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<number>0</number>
|
<item>
|
||||||
</property>
|
<widget class="QTextEdit" name="back"/>
|
||||||
<item>
|
</item>
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
</layout>
|
||||||
<property name="sizePolicy">
|
</widget>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<widget class="QWidget" name="tab_3">
|
||||||
<horstretch>10</horstretch>
|
<attribute name="title">
|
||||||
<verstretch>0</verstretch>
|
<string notr="true">STYLING</string>
|
||||||
</sizepolicy>
|
</attribute>
|
||||||
</property>
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
<property name="title">
|
<item>
|
||||||
<string>Back Template</string>
|
<widget class="QTextEdit" name="css"/>
|
||||||
</property>
|
</item>
|
||||||
<layout class="QVBoxLayout" name="tlayout3">
|
</layout>
|
||||||
<property name="spacing">
|
</widget>
|
||||||
<number>0</number>
|
</widget>
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QTextEdit" name="back"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label2">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
Loading…
Reference in New Issue
Block a user