RichText: Header/Footer can be changed by paragraph/table

git-svn-id: svn://ultimatepp.org/upp/trunk@10084 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2016-07-21 05:45:44 +00:00
parent d65073ef29
commit 4b1727cab9
25 changed files with 506 additions and 356 deletions

View file

@ -65,8 +65,29 @@ void ParaFormatting::SetupIndent()
indent.ClearModify();
}
void ParaFormatting::Set(int unit, const RichText::FormatInfo& formatinfo)
void ParaFormatting::EditHdrFtr()
{
if(EditRichHeaderFooter(header_qtf, footer_qtf))
modified = true;
}
void ParaFormatting::NewHdrFtr()
{
SyncHdrFtr();
if(newhdrftr)
EditHdrFtr();
}
void ParaFormatting::SyncHdrFtr()
{
hdrftr.Enable(newhdrftr && newhdrftr.IsEnabled());
}
void ParaFormatting::Set(int unit, const RichText::FormatInfo& formatinfo, bool baselevel)
{
page.Enable(baselevel);
newhdrftr.Enable(baselevel);
hdrftr.Enable(baselevel);
font = formatinfo;
ruler.Set(unit, RichText::RULER & formatinfo.paravalid ? formatinfo.ruler : Null);
before.Set(unit, RichText::BEFORE & formatinfo.paravalid ? formatinfo.before : Null);
@ -79,6 +100,15 @@ void ParaFormatting::Set(int unit, const RichText::FormatInfo& formatinfo)
formatinfo.align == ALIGN_CENTER ? 1 :
formatinfo.align == ALIGN_RIGHT ? 2 :
3;
if(RichText::NEWHDRFTR & formatinfo.paravalid) {
newhdrftr = formatinfo.newhdrftr;
header_qtf = formatinfo.header_qtf;
footer_qtf = formatinfo.footer_qtf;
}
else {
newhdrftr = Null;
newhdrftr.ThreeState();
}
if(RichText::NEWPAGE & formatinfo.paravalid)
page = formatinfo.newpage;
else {
@ -143,6 +173,7 @@ void ParaFormatting::Set(int unit, const RichText::FormatInfo& formatinfo)
keepindent = formatinfo.indent != ComputeIndent();
SetupIndent();
ClearModify();
SyncHdrFtr();
modified = false;
}
@ -178,6 +209,16 @@ dword ParaFormatting::Get(RichText::FormatInfo& formatinfo)
formatinfo.newpage = page;
v |= RichText::NEWPAGE;
}
if(!IsNull(newhdrftr)) {
formatinfo.newhdrftr = newhdrftr;
v |= RichText::NEWHDRFTR;
if(formatinfo.newhdrftr) {
formatinfo.header_qtf = header_qtf;
formatinfo.footer_qtf = footer_qtf;
}
else
formatinfo.header_qtf = formatinfo.footer_qtf = Null;
}
if(!IsNull(keep)) {
formatinfo.keep = keep;
v |= RichText::KEEP;
@ -284,6 +325,11 @@ ParaFormatting::ParaFormatting()
after_number <<=
reset_number <<=
bullet <<= THISBACK(SetupIndent);
newhdrftr <<= THISBACK(NewHdrFtr);
hdrftr <<= THISBACK(EditHdrFtr);
SyncHdrFtr();
EnableNumbering();
rulerink.NullText("---");
rulerstyle.SetDisplay(Single<RulerStyleDisplay>());

View file

@ -72,6 +72,8 @@ struct HeaderFooterDlg : WithHeaderFooterLayout<TopWindow> {
RichEditHdrFtr header_editor, footer_editor;
void Sync();
void Set(const String& header_qtf, const String& footer_qtf);
void Get(String& header_qtf, String& footer_qtf);
void Load(const RichText& text);
void Save(RichText& text);
@ -91,21 +93,30 @@ HeaderFooterDlg::HeaderFooterDlg()
Sync();
}
void HeaderFooterDlg::Load(const RichText& text)
void HeaderFooterDlg::Set(const String& header_qtf, const String& footer_qtf)
{
String h = text.GetHeaderQtf();
use_header = !IsNull(h);
use_header = !IsNull(header_qtf);
if(use_header)
header_editor.SetQTF(h);
header_editor.SetQTF(header_qtf);
header_editor.EvaluateFields();
h = text.GetFooterQtf();
use_footer = !IsNull(h);
use_footer = !IsNull(footer_qtf);
if(use_footer)
footer_editor.SetQTF(h);
footer_editor.SetQTF(footer_qtf);
footer_editor.EvaluateFields();
Sync();
}
void HeaderFooterDlg::Get(String& header_qtf, String& footer_qtf)
{
header_qtf = use_header ? header_editor.GetQTF() : String();
footer_qtf = use_footer ? footer_editor.GetQTF() : String();
}
void HeaderFooterDlg::Load(const RichText& text)
{
Set(text.GetHeaderQtf(), text.GetFooterQtf());
}
void HeaderFooterDlg::Save(RichText& text)
{
if(use_header)
@ -130,4 +141,15 @@ void RichEdit::HeaderFooter()
}
}
bool EditRichHeaderFooter(String& header_qtf, String& footer_qtf)
{
HeaderFooterDlg dlg;
dlg.Set(header_qtf, footer_qtf);
if(dlg.Execute() == IDOK) {
dlg.Get(header_qtf, footer_qtf);
return true;
}
return false;
}
END_UPP_NAMESPACE

View file

@ -436,13 +436,13 @@ void RichEdit::InsertLine()
}
anchor = cursor = cursor + 1;
begtabsel = false;
formatinfo.newpage = false;
formatinfo.newpage = formatinfo.newhdrftr = false;
if(st) {
Uuid next = text.GetStyle(b.styleid).next;
if(next != formatinfo.styleid) {
formatinfo.label.Clear();
formatinfo.styleid = next;
ApplyFormat(0, RichText::STYLE|RichText::NEWPAGE|RichText::LABEL);
ApplyFormat(0, RichText::STYLE|RichText::NEWPAGE|RichText::LABEL|RichText::NEWHDRFTR);
return;
}
}

View file

@ -14,8 +14,9 @@ struct ParaFormatDlg : public WithParaFormatLayout<TopWindow> {
void RichEdit::ParaFormat()
{
ParaFormatDlg d;
d.para.Set(unit, formatinfo);
if(d.Execute() != IDOK || !d.para.IsChanged()) return;
d.para.Set(unit, formatinfo, !IsSelection() && cursorp.level == 0);
if(d.Execute() != IDOK || !d.para.IsChanged())
return;
dword v = d.para.Get(formatinfo);
if(v) ApplyFormat(0, v);
}

View file

@ -123,6 +123,8 @@ struct FontHeight : public WithDropChoice<EditDouble> {
#define LAYOUTFILE <RichEdit/RichEdit.lay>
#include <CtrlCore/lay.h>
bool EditRichHeaderFooter(String& header_qtf, String& footer_qtf);
class ParaFormatting : public WithParaLayout<StaticRect> {
public:
DropList n[8];
@ -134,6 +136,7 @@ private:
bool keepindent;
Font font;
bool modified;
String header_qtf, footer_qtf;
RichPara::NumberFormat GetNumbering();
bool IsNumbering();
@ -143,12 +146,15 @@ private:
typedef ParaFormatting CLASSNAME;
public:
void Set(int unit, const RichText::FormatInfo& formatinfo);
void Set(int unit, const RichText::FormatInfo& formatinfo, bool baselevel = false);
dword Get(RichText::FormatInfo& formatinfo);
void SetFont(Font fnt) { font = fnt; }
bool IsChanged() const { return IsModified() || modified; }
void EnableNumbering();
void SetupIndent();
void EditHdrFtr();
void NewHdrFtr();
void SyncHdrFtr();
ParaFormatting();
};
@ -617,6 +623,7 @@ private:
void ApplyStyleKey(int i);
void HeaderFooter();
bool EditHeaderFooter(String& header_qtf, String& footer_qtf);
bool BegSelTabFix();
void BegSelTabFixEnd(bool fix);

View file

@ -1,52 +1,54 @@
LAYOUT(ParaLayout, 488, 352)
ITEM(LabelBox, dv___0, SetLabel(t_("Alignment")).LeftPosZ(8, 100).TopPosZ(8, 88))
LAYOUT(ParaLayout, 488, 380)
ITEM(LabelBox, dv___0, SetLabel(t_("Alignment")).LeftPosZ(8, 100).TopPosZ(8, 104))
ITEM(Switch, align, SetLabel(t_("Left\nCenter\nRight\nJustify")).LeftPosZ(16, 84).TopPosZ(24, 68))
ITEM(LabelBox, dv___2, SetLabel(t_("Spacing")).LeftPosZ(116, 176).TopPosZ(8, 88))
ITEM(LabelBox, dv___2, SetLabel(t_("Spacing")).LeftPosZ(116, 176).TopPosZ(8, 104))
ITEM(Label, dv___3, SetLabel(t_("Before")).LeftPosZ(128, 88).TopPosZ(24, 19))
ITEM(UnitEdit, before, LeftPosZ(216, 68).TopPosZ(24, 19))
ITEM(Label, dv___5, SetLabel(t_("After")).LeftPosZ(128, 88).TopPosZ(48, 19))
ITEM(UnitEdit, after, LeftPosZ(216, 68).TopPosZ(48, 19))
ITEM(Label, dv___7, SetLabel(t_("Line spacing")).LeftPosZ(128, 88).TopPosZ(72, 19))
ITEM(DropList, linespacing, LeftPosZ(216, 68).TopPosZ(72, 19))
ITEM(LabelBox, dv___9, SetLabel(t_("Text flow")).LeftPosZ(300, 180).TopPosZ(8, 88))
ITEM(LabelBox, dv___9, SetLabel(t_("Text flow")).LeftPosZ(300, 180).TopPosZ(8, 104))
ITEM(Option, page, SetLabel(t_("Break page before")).LeftPosZ(308, 164).TopPosZ(24, 16))
ITEM(Option, keep, SetLabel(t_("Keep together")).LeftPosZ(308, 164).TopPosZ(40, 16))
ITEM(Option, keepnext, SetLabel(t_("Keep with next")).LeftPosZ(308, 164).TopPosZ(56, 16))
ITEM(Option, orphan, SetLabel(t_("Allow orphans")).LeftPosZ(308, 164).TopPosZ(72, 16))
ITEM(LabelBox, dv___14, SetLabel(t_("Ruler")).LeftPosZ(8, 472).TopPosZ(100, 40))
ITEM(Label, dv___15, SetLabel(t_("Ruler height")).LeftPosZ(16, 88).TopPosZ(112, 19))
ITEM(UnitEdit, ruler, LeftPosZ(108, 68).TopPosZ(112, 19))
ITEM(Label, dv___17, SetLabel(t_("Ink")).LeftPosZ(192, 36).TopPosZ(112, 20))
ITEM(ColorPusher, rulerink, LeftPosZ(232, 92).TopPosZ(112, 19))
ITEM(Label, dv___19, SetLabel(t_("Style")).LeftPosZ(340, 36).TopPosZ(112, 20))
ITEM(DropList, rulerstyle, LeftPosZ(380, 92).TopPosZ(112, 19))
ITEM(LabelBox, dv___21, SetLabel(t_("Indentation")).LeftPosZ(8, 176).TopPosZ(144, 124))
ITEM(Label, dv___22, SetLabel(t_("Left margin")).LeftPosZ(16, 88).TopPosZ(164, 19))
ITEM(UnitEdit, lm, LeftPosZ(108, 68).TopPosZ(164, 19))
ITEM(Label, dv___24, SetLabel(t_("ParaLayout_rm_1_SetLabel\aRight margin")).LeftPosZ(16, 88).TopPosZ(188, 19))
ITEM(UnitEdit, rm, LeftPosZ(108, 68).TopPosZ(188, 19))
ITEM(Label, dv___26, SetLabel(t_("First line")).LeftPosZ(16, 88).TopPosZ(212, 19))
ITEM(UnitEdit, indent, LeftPosZ(108, 68).TopPosZ(212, 19))
ITEM(Label, dv___28, SetLabel(t_("\vBullet")).LeftPosZ(16, 104).TopPosZ(236, 24))
ITEM(DropList, bullet, LeftPosZ(124, 52).TopPosZ(236, 24))
ITEM(LabelBox, dv___30, SetLabel(t_("Tabs")).LeftPosZ(192, 288).TopPosZ(144, 124))
ITEM(ArrayCtrl, tabs, AutoHideSb(true).LeftPosZ(200, 272).TopPosZ(160, 72))
ITEM(Label, dv___32, SetLabel(t_("Default tab size")).LeftPosZ(200, 196).TopPosZ(240, 20))
ITEM(UnitEdit, tabsize, LeftPosZ(404, 68).TopPosZ(240, 19))
ITEM(LabelBox, dv___34, SetLabel(t_("Numbering")).LeftPosZ(8, 472).TopPosZ(276, 68))
ITEM(Label, dv___35, SetLabel(t_("Before number")).LeftPosZ(16, 100).TopPosZ(292, 20))
ITEM(EditString, before_number, LeftPosZ(116, 72).TopPosZ(292, 19))
ITEM(Label, dv___37, SetLabel(t_("After number")).LeftPosZ(208, 100).TopPosZ(292, 20))
ITEM(EditString, after_number, LeftPosZ(308, 72).TopPosZ(292, 19))
ITEM(Option, reset_number, SetLabel(t_("Reset")).LeftPosZ(396, 72).TopPosZ(292, 20))
UNTYPED(n[0], LeftPosZ(16, 54).TopPosZ(320, 19))
UNTYPED(n[1], LeftPosZ(72, 54).TopPosZ(320, 19))
UNTYPED(n[2], LeftPosZ(128, 54).TopPosZ(320, 19))
UNTYPED(n[3], LeftPosZ(184, 54).TopPosZ(320, 19))
UNTYPED(n[4], LeftPosZ(240, 54).TopPosZ(320, 19))
UNTYPED(n[5], LeftPosZ(296, 54).TopPosZ(320, 19))
UNTYPED(n[6], LeftPosZ(352, 54).TopPosZ(320, 19))
UNTYPED(n[7], LeftPosZ(408, 54).TopPosZ(320, 19))
ITEM(Option, newhdrftr, SetLabel(t_("New header / footer")).LeftPosZ(308, 148).TopPosZ(88, 16))
ITEM(LabelBox, dv___15, SetLabel(t_("Ruler")).LeftPosZ(8, 472).TopPosZ(120, 40))
ITEM(Label, dv___16, SetLabel(t_("Ruler height")).LeftPosZ(16, 88).TopPosZ(132, 19))
ITEM(UnitEdit, ruler, LeftPosZ(108, 68).TopPosZ(132, 19))
ITEM(Label, dv___18, SetLabel(t_("Ink")).LeftPosZ(192, 36).TopPosZ(132, 20))
ITEM(ColorPusher, rulerink, LeftPosZ(232, 92).TopPosZ(132, 19))
ITEM(Label, dv___20, SetLabel(t_("Style")).LeftPosZ(340, 36).TopPosZ(132, 20))
ITEM(DropList, rulerstyle, LeftPosZ(380, 92).TopPosZ(132, 19))
ITEM(LabelBox, dv___22, SetLabel(t_("Indentation")).LeftPosZ(8, 176).TopPosZ(168, 124))
ITEM(Label, dv___23, SetLabel(t_("Left margin")).LeftPosZ(16, 88).TopPosZ(188, 19))
ITEM(UnitEdit, lm, LeftPosZ(108, 68).TopPosZ(188, 19))
ITEM(Label, dv___25, SetLabel(t_("ParaLayout_rm_1_SetLabel\aRight margin")).LeftPosZ(16, 88).TopPosZ(212, 19))
ITEM(UnitEdit, rm, LeftPosZ(108, 68).TopPosZ(212, 19))
ITEM(Label, dv___27, SetLabel(t_("First line")).LeftPosZ(16, 88).TopPosZ(236, 19))
ITEM(UnitEdit, indent, LeftPosZ(108, 68).TopPosZ(236, 19))
ITEM(Label, dv___29, SetLabel(t_("\vBullet")).LeftPosZ(16, 104).TopPosZ(260, 24))
ITEM(DropList, bullet, LeftPosZ(124, 52).TopPosZ(260, 24))
ITEM(LabelBox, dv___31, SetLabel(t_("Tabs")).LeftPosZ(192, 288).TopPosZ(168, 124))
ITEM(ArrayCtrl, tabs, AutoHideSb(true).LeftPosZ(200, 272).TopPosZ(184, 72))
ITEM(Label, dv___33, SetLabel(t_("Default tab size")).LeftPosZ(200, 196).TopPosZ(264, 20))
ITEM(UnitEdit, tabsize, LeftPosZ(404, 68).TopPosZ(264, 19))
ITEM(LabelBox, dv___35, SetLabel(t_("Numbering")).LeftPosZ(8, 472).TopPosZ(300, 68))
ITEM(Label, dv___36, SetLabel(t_("Before number")).LeftPosZ(16, 100).TopPosZ(316, 20))
ITEM(EditString, before_number, LeftPosZ(116, 72).TopPosZ(316, 19))
ITEM(Label, dv___38, SetLabel(t_("After number")).LeftPosZ(208, 100).TopPosZ(316, 20))
ITEM(EditString, after_number, LeftPosZ(308, 72).TopPosZ(316, 19))
ITEM(Option, reset_number, SetLabel(t_("Reset")).LeftPosZ(396, 72).TopPosZ(316, 20))
UNTYPED(n[0], LeftPosZ(16, 54).TopPosZ(344, 19))
UNTYPED(n[1], LeftPosZ(72, 54).TopPosZ(344, 19))
UNTYPED(n[2], LeftPosZ(128, 54).TopPosZ(344, 19))
UNTYPED(n[3], LeftPosZ(184, 54).TopPosZ(344, 19))
UNTYPED(n[4], LeftPosZ(240, 54).TopPosZ(344, 19))
UNTYPED(n[5], LeftPosZ(296, 54).TopPosZ(344, 19))
UNTYPED(n[6], LeftPosZ(352, 54).TopPosZ(344, 19))
UNTYPED(n[7], LeftPosZ(408, 54).TopPosZ(344, 19))
ITEM(Button, hdrftr, SetLabel(t_("...")).LeftPosZ(452, 20).TopPosZ(88, 16))
END_LAYOUT
LAYOUT(SetStyleLayout, 216, 280)
@ -84,33 +86,33 @@ LAYOUT(ObjectSizeLayout, 290, 102)
ITEM(Button, cancel, SetLabel(t_("Cancel")).RightPosZ(4, 64).BottomPosZ(4, 24))
END_LAYOUT
LAYOUT(ParaFormatLayout, 488, 396)
UNTYPED(para, LeftPosZ(0, 488).TopPosZ(0, 352))
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(348, 64).TopPosZ(364, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(416, 64).TopPosZ(364, 24))
LAYOUT(ParaFormatLayout, 488, 416)
UNTYPED(para, LeftPosZ(0, 488).TopPosZ(0, 380))
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(352, 64).TopPosZ(388, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(420, 64).TopPosZ(388, 24))
END_LAYOUT
LAYOUT(StylesLayout, 700, 496)
ITEM(ArrayCtrl, list, AutoHideSb(true).LeftPosZ(8, 196).TopPosZ(8, 480))
UNTYPED(para, LeftPosZ(204, 496).TopPosZ(0, 352))
ITEM(Label, dv___2, SetLabel(t_("Font")).LeftPosZ(224, 52).TopPosZ(380, 20))
ITEM(DropList, face, LeftPosZ(280, 172).TopPosZ(381, 19))
ITEM(Label, dv___4, SetLabel(t_("Height")).LeftPosZ(476, 104).TopPosZ(380, 20))
UNTYPED(height, LeftPosZ(580, 64).TopPosZ(380, 19))
ITEM(Option, italic, SetLabel(t_("Italic")).LeftPosZ(224, 64).TopPosZ(409, 18))
ITEM(Option, bold, SetLabel(t_("Bold")).LeftPosZ(224, 64).TopPosZ(428, 18))
ITEM(Option, underline, SetLabel(t_("Underline")).LeftPosZ(292, 76).TopPosZ(408, 18))
ITEM(Option, strikeout, SetLabel(t_("Strikeout")).LeftPosZ(292, 74).TopPosZ(428, 18))
ITEM(Option, capitals, SetLabel(t_("Capitals")).LeftPosZ(372, 88).TopPosZ(408, 18))
ITEM(Label, dv___11, SetLabel(t_("Ink")).LeftPosZ(476, 104).TopPosZ(404, 20))
ITEM(ColorPusher, ink, LeftPosZ(580, 92).TopPosZ(404, 19))
ITEM(Label, dv___13, SetLabel(t_("Paper")).LeftPosZ(476, 104).TopPosZ(428, 20))
ITEM(ColorPusher, paper, LeftPosZ(580, 92).TopPosZ(428, 19))
ITEM(Label, dv___15, SetLabel(t_("Style of next paragraph")).LeftPosZ(212, 152).TopPosZ(468, 20))
ITEM(DropList, next, LeftPosZ(368, 132).TopPosZ(468, 19))
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(560, 64).TopPosZ(464, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(628, 64).TopPosZ(464, 24))
ITEM(LabelBox, dv___19, SetLabel(t_("Character")).LeftPosZ(212, 472).TopPosZ(360, 96))
LAYOUT(StylesLayout, 700, 524)
ITEM(ArrayCtrl, list, AutoHideSb(true).LeftPosZ(8, 196).TopPosZ(8, 508))
UNTYPED(para, LeftPosZ(204, 496).TopPosZ(0, 380))
ITEM(Label, dv___2, SetLabel(t_("Font")).LeftPosZ(224, 52).TopPosZ(408, 20))
ITEM(DropList, face, LeftPosZ(280, 172).TopPosZ(409, 19))
ITEM(Label, dv___4, SetLabel(t_("Height")).LeftPosZ(476, 104).TopPosZ(408, 20))
UNTYPED(height, LeftPosZ(580, 64).TopPosZ(408, 19))
ITEM(Option, italic, SetLabel(t_("Italic")).LeftPosZ(224, 64).TopPosZ(437, 18))
ITEM(Option, bold, SetLabel(t_("Bold")).LeftPosZ(224, 64).TopPosZ(456, 18))
ITEM(Option, underline, SetLabel(t_("Underline")).LeftPosZ(292, 76).TopPosZ(436, 18))
ITEM(Option, strikeout, SetLabel(t_("Strikeout")).LeftPosZ(292, 74).TopPosZ(456, 18))
ITEM(Option, capitals, SetLabel(t_("Capitals")).LeftPosZ(372, 88).TopPosZ(436, 18))
ITEM(Label, dv___11, SetLabel(t_("Ink")).LeftPosZ(476, 104).TopPosZ(432, 20))
ITEM(ColorPusher, ink, LeftPosZ(580, 92).TopPosZ(432, 19))
ITEM(Label, dv___13, SetLabel(t_("Paper")).LeftPosZ(476, 104).TopPosZ(456, 20))
ITEM(ColorPusher, paper, LeftPosZ(580, 92).TopPosZ(456, 19))
ITEM(Label, dv___15, SetLabel(t_("Style of next paragraph")).LeftPosZ(212, 152).TopPosZ(496, 20))
ITEM(DropList, next, LeftPosZ(368, 132).TopPosZ(496, 19))
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(560, 64).TopPosZ(492, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(628, 64).TopPosZ(492, 24))
ITEM(LabelBox, dv___19, SetLabel(t_("Character")).LeftPosZ(212, 472).TopPosZ(388, 96))
END_LAYOUT
LAYOUT(RichFindReplaceLayout, 264, 128)
@ -139,7 +141,7 @@ LAYOUT(CreateTableLayout, 164, 88)
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(92, 64).TopPosZ(56, 24))
END_LAYOUT
LAYOUT(TablePropertiesLayout, 328, 188)
LAYOUT(TablePropertiesLayout, 340, 244)
ITEM(Label, dv___0, SetLabel(t_("Before")).LeftPosZ(8, 72).TopPosZ(8, 19))
ITEM(UnitEdit, before, LeftPosZ(84, 68).TopPosZ(8, 19))
ITEM(Label, dv___2, SetLabel(t_("After")).LeftPosZ(168, 76).TopPosZ(8, 19))
@ -158,12 +160,15 @@ LAYOUT(TablePropertiesLayout, 328, 188)
ITEM(ColorPusher, gridcolor, LeftPosZ(248, 68).TopPosZ(80, 19))
ITEM(Label, dv___16, SetLabel(t_("Header")).LeftPosZ(8, 72).TopPosZ(104, 19))
ITEM(EditIntSpin, header, LeftPosZ(84, 68).TopPosZ(104, 19))
ITEM(Option, keep, SetLabel(t_("Keep rows together")).LeftPosZ(168, 136).TopPosZ(104, 20))
ITEM(Option, equalize, SetLabel(t_("Equalize")).LeftPosZ(8, 64).TopPosZ(130, 20))
ITEM(EditString, ratios, LeftPosZ(72, 248).TopPosZ(130, 19))
ITEM(Button, destroy, SetLabel(t_("Remove table")).LeftPosZ(8, 96).TopPosZ(158, 24))
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(188, 64).TopPosZ(158, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(256, 64).TopPosZ(158, 24))
ITEM(Option, equalize, SetLabel(t_("Equalize")).LeftPosZ(8, 76).TopPosZ(128, 20))
ITEM(EditString, ratios, LeftPosZ(84, 248).TopPosZ(128, 19))
ITEM(Option, keep, SetLabel(t_("Keep rows together")).LeftPosZ(8, 136).TopPosZ(152, 20))
ITEM(Option, newpage, SetLabel(t_("Break page before")).LeftPosZ(8, 164).TopPosZ(172, 16))
ITEM(Option, newhdrftr, SetLabel(t_("New header / footer")).LeftPosZ(8, 148).TopPosZ(188, 16))
ITEM(Button, hdrftr, SetLabel(t_("...")).LeftPosZ(152, 20).TopPosZ(188, 16))
ITEM(Button, destroy, SetLabel(t_("Remove table")).LeftPosZ(8, 96).TopPosZ(212, 24))
ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(200, 64).TopPosZ(212, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(268, 64).TopPosZ(212, 24))
END_LAYOUT
LAYOUT(SplitCellLayout, 148, 92)
@ -214,13 +219,13 @@ LAYOUT(StyleKeysLayout, 736, 556)
ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(664, 64).TopPosZ(524, 24))
END_LAYOUT
LAYOUT(HeaderFooterLayout, 548, 580)
LAYOUT(HeaderFooterLayout, 680, 580)
ITEM(Option, use_header, SetLabel(t_("Use header")).LeftPosZ(4, 120).TopPosZ(4, 16))
UNTYPED(header_editor, HSizePosZ(0, 0).TopPosZ(24, 240))
UNTYPED(header_editor, HSizePosZ(0, 4).TopPosZ(24, 240))
ITEM(Option, use_footer, SetLabel(t_("Use footer")).LeftPosZ(4, 120).VSizePosZ(280, 284))
UNTYPED(footer_editor, HSizePosZ(0, 0).BottomPosZ(40, 240))
ITEM(Button, ok, SetLabel(t_("OK")).RightPosZ(76, 64).BottomPosZ(8, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).RightPosZ(8, 64).BottomPosZ(8, 24))
ITEM(LabelBox, dv___6, LeftPosZ(0, 548).TopPosZ(260, 24))
UNTYPED(footer_editor, HSizePosZ(0, 4).BottomPosZ(40, 240))
ITEM(Button, ok, SetLabel(t_("OK")).RightPosZ(72, 64).BottomPosZ(8, 24))
ITEM(Button, cancel, SetLabel(t_("Cancel")).RightPosZ(4, 64).BottomPosZ(8, 24))
ITEM(LabelBox, dv___6, LeftPosZ(0, 676).TopPosZ(260, 24))
END_LAYOUT

View file

@ -88,12 +88,41 @@ int CharFilterEqualize(int c)
return IsDigit(c) || c == ':' ? c : 0;
}
struct RichEditTableProperties : WithTablePropertiesLayout<TopWindow> {
String header_qtf, footer_qtf;
void EditHdrFtr()
{
EditRichHeaderFooter(header_qtf, footer_qtf);
}
void NewHdrFtr()
{
SyncHdrFtr();
if(newhdrftr)
EditHdrFtr();
}
void SyncHdrFtr()
{
hdrftr.Enable(newhdrftr && newhdrftr.IsEnabled());
}
typedef RichEditTableProperties CLASSNAME;
RichEditTableProperties() {
CtrlLayoutOKCancel(*this, t_("Table properties"));
newhdrftr <<= THISBACK(NewHdrFtr);
hdrftr <<= THISBACK(EditHdrFtr);
SyncHdrFtr();
}
};
void RichEdit::TableProps()
{
if(IsSelection() || cursorp.table == 0)
return;
WithTablePropertiesLayout<TopWindow> dlg;
CtrlLayoutOKCancel(dlg, t_("Table properties"));
RichEditTableProperties dlg;
dlg.Breaker(dlg.destroy, IDNO);
RichTable::Format fmt = text.GetTableFormat(cursorp.table);
String ratios;
@ -114,7 +143,15 @@ void RichEdit::TableProps()
Advn(r, dlg.grid.SetUnit(unit), fmt.grid);
Advn(r, dlg.header, fmt.header);
Advn(r, dlg.keep, fmt.keep);
Advn(r, dlg.newpage, fmt.newpage);
Advn(r, dlg.newhdrftr, fmt.newhdrftr);
dlg.header_qtf = fmt.header_qtf;
dlg.footer_qtf = fmt.footer_qtf;
r(dlg.gridcolor, fmt.gridcolor);
dlg.SyncHdrFtr();
dlg.newpage.Enable(cursorp.level == 1);
dlg.newhdrftr.Enable(cursorp.level == 1);
dlg.hdrftr.Enable(cursorp.level == 1);
for(;;) {
switch(dlg.Run()) {
case IDCANCEL:
@ -125,6 +162,12 @@ void RichEdit::TableProps()
return;
default:
r.Retrieve();
if(dlg.newhdrftr) {
fmt.header_qtf = dlg.header_qtf;
fmt.footer_qtf = dlg.footer_qtf;
}
else
fmt.header_qtf = fmt.footer_qtf = Null;
const RichTable& tbl = text.GetConstTable(cursorp.table);
bool valid = true;
Point violator(0, 0);

View file

@ -129,6 +129,9 @@ void QTFEncodeParaFormat(String& qtf, const RichPara::Format& format, const Rich
}
if(!IsEmpty(format.label))
qtf << ':' << DeQtf(format.label) << ':';
if(style.newhdrftr != format.newhdrftr)
qtf << "tP" << format.header_qtf << "^^" << format.footer_qtf << "^^";
if(NumberingDiffers(style, format)) {
if(format.before_number != style.before_number) {
qtf << "n";
@ -305,7 +308,7 @@ void QTFEncodePara(String& qtf, const RichPara& p, const RichPara::Format& style
qtf.Cat(':');
else {
qtf.Cat('`');
qtf.Cat(c);
qtf.Cat(c);
d += 2;
}
if(crlf && d > 60 && c == ' ') {
@ -389,7 +392,11 @@ void QTFEncodeTxt(String& qtf, const RichTxt& text, const RichStyles& styles, co
FmtNumber(qtf, 'A', d.after, f.after);
FmtNumber(qtf, 'f', d.frame, f.frame);
if(f.keep)
qtf << "K";
qtf << 'K';
if(f.newpage)
qtf << 'P';
if(f.newhdrftr)
qtf << 'T' << f.header_qtf << "^^" << f.footer_qtf << "^^";
if(f.framecolor != d.framecolor)
qtf << 'F' << QtfFormat(f.framecolor);
FmtNumber(qtf, 'g', d.grid, f.grid);
@ -481,11 +488,11 @@ String AsQTF(const RichText& text, byte charset, dword options)
// for(i = 0; i < text.GetPartCount(); i++)
// sm.FindAdd(text.GetParaStyle(i));
String hdr = text.GetHeaderQtf(charset, options);
String hdr = text.GetHeaderQtf();
if(hdr.GetCount())
qtf << "^H" << hdr << "^^\r\n";
String ftr = text.GetFooterQtf(charset, options);
String ftr = text.GetFooterQtf();
if(ftr.GetCount())
qtf << "^F" << ftr << "^^\r\n";

View file

@ -126,6 +126,8 @@ void RichTxt::FormatInfo::Combine(const RichPara::Format& fmt)
paravalid &= ~RULERINK;
if(rulerstyle != fmt.rulerstyle)
paravalid &= ~RULERSTYLE;
if(newhdrftr != fmt.newhdrftr)
paravalid &= ~NEWHDRFTR;
}
void RichTxt::FormatInfo::ApplyTo(RichPara::CharFormat& fmt) const
@ -211,6 +213,11 @@ void RichTxt::FormatInfo::ApplyTo(RichPara::Format& fmt) const
fmt.rulerink = rulerink;
if(paravalid & RULERSTYLE)
fmt.rulerstyle = rulerstyle;
if(paravalid & NEWHDRFTR) {
fmt.newhdrftr = newhdrftr;
fmt.header_qtf = header_qtf;
fmt.footer_qtf = footer_qtf;
}
}
END_UPP_NAMESPACE

View file

@ -20,83 +20,70 @@ INITBLOCK {
RichPara::Register<RichNumberField>("VALUE");
}
Rect RichText::GetPageMinusHeaderFooter(const Rect& page) const
RichText GetHeaderFooterText(const String& qtf, int page, int pagecount)
{
Rect p = page;
VectorMap<String, Value> vars;
vars.Add("PAGENUMBER", 999999999);
vars.Add("PAGECOUNT", 999999999);
if(header) {
header->EvaluateFields(vars);
p.top += header->GetHeight(page.GetWidth());
}
if(footer) {
footer->EvaluateFields(vars);
p.bottom -= footer->GetHeight(page.GetWidth());
}
return p.GetHeight() > page.GetHeight() / 2 ? p : page;
vars.Add("PAGENUMBER", page + 1);
vars.Add("PAGECOUNT", pagecount);
RichText txt = ParseQTF(qtf);
txt.EvaluateFields(vars);
return txt;
}
void RichContext::NewHeaderFooter(const String& header_qtf_, const String& footer_qtf_)
{
page.top -= header_cy;
page.bottom += footer_cy;
header_qtf = header_qtf_;
footer_qtf = footer_qtf_;
header_cy = header_qtf.GetCount() ? GetHeaderFooterText(header_qtf, 999990, 999990).GetHeight(page.GetWidth()) : 0;
footer_cy = footer_qtf.GetCount() ? GetHeaderFooterText(footer_qtf, 999990, 999990).GetHeight(page.GetWidth()) : 0;
page.top += header_cy;
page.bottom -= footer_cy;
}
RichContext RichText::Context(const Rect& page, PageY py, const String& header_qtf, const String& footer_qtf) const
{
RichContext rc(style, this);
rc.page = page;
rc.py = py;
rc.NewHeaderFooter(header_qtf, footer_qtf);
if(rc.py.y < rc.page.top)
rc.py.y = rc.page.top;
return rc;
}
void RichText::PaintHeaderFooter(PageDraw& pw, const Rect& page, const PaintInfo& pi_,
int from_page, int to_page) const
{
Rect rpage = GetPageMinusHeaderFooter(page);
if(rpage == page)
return;
PaintInfo pi = pi_;
pi.sell = pi.selh = 0;
VectorMap<String, Value> vars;
vars.Add("PAGECOUNT", GetHeight(page).page + 1);
for(int i = from_page; i <= to_page; i++) {
vars.GetAdd("PAGENUMBER") = i + 1;
if(header) {
header->EvaluateFields(vars);
header->Paint(pw, PageY(i, page.top), page, pi);
}
if(footer) {
footer->EvaluateFields(vars);
Rect pr = page;
pr.top = rpage.bottom;
footer->Paint(pw, PageY(i, pr.top), page, pi);
RichContext rc = Context(page);
int last_page = -1;
int pagecount = GetHeight(page).page + 1;
for(int i = 0; i < GetPartCount() && last_page < to_page; i++) {
while(last_page < rc.py.page) {
last_page++;
if(rc.header_qtf.GetCount())
GetHeaderFooterText(rc.header_qtf, last_page, pagecount).Paint(pw, PageY(last_page, page.top), page, pi);
if(rc.footer_qtf.GetCount())
GetHeaderFooterText(rc.footer_qtf, last_page, pagecount).Paint(pw, PageY(last_page, page.bottom - rc.footer_cy), page, pi);
}
RichContext begin;
Advance(i, rc, begin);
}
}
void RichText::PickHeader(RichText&& txt)
void RichTxt::SetHeaderQtf(const char *qtf)
{
RichText b = pick(txt);
b.ClearHeader();
header.Create() = pick(b);
header_qtf = qtf;
r_type = ALL;
}
void RichText::PickFooter(RichText&& txt)
void RichTxt::SetFooterQtf(const char *qtf)
{
RichText b = pick(txt);
b.ClearFooter();
footer.Create() = pick(b);
}
void RichText::SetHeaderQtf(const char *qtf)
{
header.Clear();
if(qtf)
PickHeader(ParseQTF(qtf));
}
void RichText::SetFooterQtf(const char *qtf)
{
if(qtf)
PickFooter(ParseQTF(qtf));
}
String RichText::GetHeaderQtf(byte charset, dword options) const
{
return header ? AsQTF(*header, charset, options) : String();
}
String RichText::GetFooterQtf(byte charset, dword options) const
{
return footer ? AsQTF(*footer, charset, options) : String();
footer_qtf = qtf;
r_type = ALL;
}
END_UPP_NAMESPACE

View file

@ -127,7 +127,8 @@ struct RichPara {
int tabsize;
int bullet;
int linespacing;
bool newpage, keep, keepnext, orphan;
bool newpage, keep, keepnext, orphan, newhdrftr;
String header_qtf, footer_qtf;
void SortTabs();
@ -264,15 +265,11 @@ struct RichPara {
void GetRichPos(RichPos& rp, int pos) const;
Lines FormatLines(int cx) const;
void Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo& pi,
const Number& n, const Bits& spellerrors,
int nbefore, int nline) const;
RichCaret GetCaret(int pos, const Rect& page, PageY py, int nbefore, int nline) const;
int GetPos(int x, PageY y, const Rect& page, PageY py, int nbefore, int nline) const;
void GatherLabels(Vector<RichValPos>& info, const Rect& page, PageY py,
int pos, int nbefore, int nline) const;
void GatherIndexes(Vector<RichValPos>& info, const Rect& page, PageY py,
int pos, int nbefore, int nline) const;
void Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo& pi, const Number& n, const Bits& spellerror, bool baselevel) const;
RichCaret GetCaret(int pos, const Rect& page, PageY py) const;
int GetPos(int x, PageY y, const Rect& page, PageY py) const;
void GatherLabels(Vector<RichValPos>& info, const Rect& page, PageY py, int pos) const;
void GatherIndexes(Vector<RichValPos>& info, const Rect& page, PageY py, int pos) const;
int GetVertMove(int pos, int gx, const Rect& page, int dir) const;
WString GetText() const;
@ -299,7 +296,7 @@ struct RichPara {
private:
Tab GetNextTab(int pos, int cx) const;
void Smh(Lines& lines, HeightInfo *th, int cx) const;
Lines Begin(const Rect& page, PageY& py, int nbefore, int nline) const;
Lines Begin(const Rect& page, PageY& py) const;
bool BreaksPage(PageY py, const Lines& pl, int i, const Rect& page) const;
void PackParts(Stream& out, const CharFormat& chrstyle,
const Array<Part>& part, CharFormat& cf,

View file

@ -171,7 +171,7 @@ RichPara::Format::Format()
rulerink = Black;
rulerstyle = RULER_SOLID;
bullet = 0;
keep = newpage = keepnext = orphan = false;
keep = newpage = keepnext = orphan = newhdrftr = false;
tabsize = 296;
memset(number, 0, sizeof(number));
reset_number = false;
@ -341,6 +341,8 @@ String RichPara::Pack(const RichPara::Format& style, Array<RichObject>& obj) con
if(format.ruler != style.ruler) pattr |= 0x10000;
if(format.rulerink != style.rulerink) pattr |= 0x20000;
if(format.rulerstyle != style.rulerstyle) pattr |= 0x40000;
if(format.newhdrftr != style.newhdrftr) pattr |= 0x80000;
out.Put32(pattr);
if(pattr & 1) out.Put16(format.align);
if(pattr & 2) out.Put16(format.before);
@ -388,6 +390,16 @@ String RichPara::Pack(const RichPara::Format& style, Array<RichObject>& obj) con
}
if(pattr & 0x40000)
out.Put16(format.rulerstyle);
if(pattr & 0x80000) {
out.Put(format.newhdrftr);
if(format.newhdrftr) {
String t = format.header_qtf;
String f = format.footer_qtf;
out % t % f;
}
}
obj.Clear();
CharFormat cf = style;
if(part.GetCount())
@ -612,6 +624,13 @@ void RichPara::Unpack(const String& data, const Array<RichObject>& obj,
format.rulerink.Serialize(in);
if(pattr & 0x40000)
format.rulerstyle = in.Get16();
if(pattr & 0x80000) {
format.newhdrftr = in.Get();
if(format.newhdrftr)
in % format.header_qtf % format.footer_qtf;
}
part.Clear();
int oi = 0;
UnpackParts(in, style, part, obj, oi);

View file

@ -6,9 +6,10 @@ NAMESPACE_UPP
#define IMAGEFILE <RichText/RichText.iml>
#include <Draw/iml.h>
RichPara::Lines RichPara::Begin(const Rect& page, PageY& py, int nbefore, int nline) const
RichPara::Lines RichPara::Begin(const Rect& page, PageY& py) const
{
Lines pl = FormatLines(page.Width());
#if 0 // pagination logic moved to RichTxt
int cy = format.ruler + format.before;
if(format.keep || format.keepnext)
cy += pl.BodyHeight();
@ -18,11 +19,12 @@ RichPara::Lines RichPara::Begin(const Rect& page, PageY& py, int nbefore, int nl
if(!format.keepnext)
nbefore = nline = after = 0;
if(page.Height() < 32000 &&
(format.newpage || py.y + cy + after + nbefore + nline > page.bottom &&
cy < page.Height())) {
(format.newpage || py.y + cy + after + nbefore + nline > page.bottom && cy < page.Height() ||
format.header_qtf.GetCount() + format.footer_qtf.GetCount()/* && rc.level == 0*/)) {
py.page++;
py.y = page.top;
}
#endif
py.y += format.before + format.ruler;
pl.Justify(format);
return pl;
@ -182,12 +184,11 @@ void RichPara::DrawRuler(Draw& w, int x, int y, int cx, int cy, Color ink, int s
}
void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo& pi,
const Number& n, const Bits& spellerror,
int nbefore, int nline) const
const Number& n, const Bits& spellerror, bool baselevel) const
{
Zoom z = pi.zoom;
PageY opy = py;
Lines pl = Begin(page, py, nbefore, nline);
Lines pl = Begin(page, py);
if(pw.tracer) {
PageY h = py;
h.y -= format.before + format.ruler;
@ -401,7 +402,7 @@ void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo&
pw.Page(py.page).DrawImage(z * x, z * y0 - sz.cy,
RichTextImg::EndParaChar(),
format.indexentry.GetCount() ? pi.indexentry : pi.showcodes);
if(format.newpage && !IsNull(pi.showcodes)) {
if((format.newpage || format.newhdrftr) && !IsNull(pi.showcodes) && baselevel) {
Draw& w = pw.Page(opy.page);
int wd = z * page.right - z * page.left;
int step = w.Pixels() ? 8 : 50;
@ -444,9 +445,9 @@ void RichPara::GetRichPos(RichPos& rp, int pos) const
rp.chr = '\n';
}
RichCaret RichPara::GetCaret(int pos, const Rect& page, PageY py, int nbefore, int nline) const
RichCaret RichPara::GetCaret(int pos, const Rect& page, PageY py) const
{
Lines pl = Begin(page, py, nbefore, nline);
Lines pl = Begin(page, py);
RichCaret pr;
FontInfo fi = format.Info();
pr.caretascent = fi.GetAscent();
@ -513,9 +514,9 @@ int RichPara::PosInLine(int x, const Rect& page, const Lines& pl, int lni) const
return pos < pl.clen ? pl.pos[pos] : pl.len;
}
int RichPara::GetPos(int x, PageY y, const Rect& page, PageY py, int nbefore, int nline) const
int RichPara::GetPos(int x, PageY y, const Rect& page, PageY py) const
{
Lines pl = Begin(page, py, nbefore, nline);
Lines pl = Begin(page, py);
if(pl.len)
for(int lni = 0; lni < pl.GetCount(); lni++) {
const Line& li = pl[lni];
@ -550,10 +551,9 @@ int RichPara::GetVertMove(int pos, int gx, const Rect& page, int dir) const
return PosInLine(gx, page, pl, lni);
}
void RichPara::GatherLabels(Vector<RichValPos>& info, const Rect& page, PageY py,
int pos, int nbefore, int nline) const
void RichPara::GatherLabels(Vector<RichValPos>& info, const Rect& page, PageY py, int pos) const
{
Lines pl = Begin(page, py, nbefore, nline);
Lines pl = Begin(page, py);
WString ie;
if(!pl.GetCount())
return;
@ -569,10 +569,9 @@ void RichPara::GatherLabels(Vector<RichValPos>& info, const Rect& page, PageY p
f.data = format.label.ToWString();
}
void RichPara::GatherIndexes(Vector<RichValPos>& info, const Rect& page, PageY py,
int pos, int nbefore, int nline) const
void RichPara::GatherIndexes(Vector<RichValPos>& info, const Rect& page, PageY py, int pos) const
{
Lines pl = Begin(page, py, nbefore, nline);
Lines pl = Begin(page, py);
WString ie;
for(int lni = 0; lni < pl.GetCount(); lni++) {
Line& li = pl[lni];

View file

@ -425,9 +425,15 @@ void RichQtfParser::TableFormat(bool bw)
case '@': t.format.color = GetColor(); break;
case 'R': t.format.bordercolor = GetColor(); break;
case '!': t.format = RichCell::Format(); break;
case 'k': t.format.keep = true;
case 'o': t.format.round = true;
case 'K': tab.format.keep = true;
case 'o': t.format.round = true; break;
case 'k': t.format.keep = true; break;
case 'K': tab.format.keep = true; break;
case 'P': tab.format.newpage = true; break;
case 'T':
tab.format.newhdrftr = true;
tab.format.header_qtf = GetText2('^', '^');
tab.format.footer_qtf = GetText2('^', '^');
break;
case 'a':
Number2(a, b);
if(a >= 0)
@ -774,7 +780,14 @@ void RichQtfParser::Parse(const char *qtf, int _accesskey)
}
break;
case 't':
if(IsDigit(*term)) //temporary fix... :(
if(*term == 'P') {
term++;
format.newhdrftr = true;
format.header_qtf = GetText2('^', '^');
format.footer_qtf = GetText2('^', '^');
}
else
if(IsDigit(*term))
format.tabsize = ReadNumber();
break;
case '~': {

View file

@ -243,9 +243,9 @@ enum {
RICHHOT_RM = -2,
};
struct RichHotPos {
struct RichHotPos { // used for resizing table dimensions by mouse
int table;
int column;
int column; // can be RICHHOT_LM or RICHHOT_RM or columns index
int delta;
int left, cx;
int textleft, textcx;
@ -360,14 +360,21 @@ typedef ArrayMap<Uuid, RichStyle> RichStyles;
const RichStyle& GetStyle(const RichStyles& s, const Uuid& id);
int FindStyleWithName(const RichStyles& style, const String& name);
class RichText;
struct RichContext {
const RichStyles& styles;
const RichText *text;
const RichStyles *styles;
String header_qtf, footer_qtf;
int header_cy, footer_cy;
Rect page;
PageY py;
void NewHeaderFooter(const String& header_qtf, const String& footer_qtf);
void Page() { py.page++; py.y = page.top; }
RichContext(const RichStyles& styles) : styles(styles) {}
RichContext(const RichStyles& styles, const RichText *text) : styles(&styles), text(text) { header_cy = footer_cy = 0; }
RichContext() {}
};
struct RichCellPos;

View file

@ -13,6 +13,7 @@ file
ParaType.cpp,
ParaPaint.cpp,
Txt.h,
HeaderFooter.cpp,
TxtData.cpp,
TxtPaint.cpp,
TxtOp.cpp,
@ -24,7 +25,6 @@ file
TableData.cpp,
Text.h,
TextPaint.cpp,
HeaderFooter.cpp,
TextStyle.cpp,
TextData.cpp,
TextTable.cpp,

View file

@ -50,14 +50,15 @@ public:
class RichTable : DeepCopyOption<RichTable> {
public:
struct Format {
int before, lm, rm, after;
int frame;
Color framecolor;
int grid;
Color gridcolor;
int before, lm, rm, after;
int frame;
Color framecolor;
int grid;
Color gridcolor;
WithDeepCopy< Vector<int> > column;
int header;
bool keep;
int header;
bool keep, newpage, newhdrftr;
String header_qtf, footer_qtf;
Format();
};
@ -118,12 +119,12 @@ private:
TabLayout() {}
};
mutable TabLayout clayout;
mutable TabLayout clayout; // TODO: MT?
mutable Rect cpage;
mutable PageY cpy;
Buffer< Buffer<CellInfo> > ci;
int r_row, r_column;
int r_row, r_column; // r_ - refresh info
Rect r_page;
PageY r_py, r_pyy;

View file

@ -14,10 +14,11 @@ bool RichTable::Reduce(RichContext& rc) const
}
const RichTable::TabLayout& RichTable::Realize(RichContext rc) const
{
{ // Create page layout with header
if(rc.py != cpy || rc.page != cpage) {
rc.py.y += format.before;
if(rc.py.y > rc.page.bottom) {
// TODO: header/footer adjustment here
rc.py.y = rc.page.top;
rc.py.page++;
}
@ -32,15 +33,16 @@ const RichTable::TabLayout& RichTable::Realize(RichContext rc) const
RichContext nrc = rc;
nrc.py.page = 0;
nrc.py.y = clayout.page.top;
clayout.header = Realize(nrc, hy);
if(clayout.header[0].py.page == clayout.header[hy - 1].pyy.page) {
clayout.header = Realize(nrc, hy); // realize header as if first on page
if(clayout.header[0].py.page == clayout.header[hy - 1].pyy.page) { // header fits single page
Layout x = Realize(rc, cell.GetCount());
if(cell.GetCount() > hy && rc.py.page != x[hy].py.page) {
if(cell.GetCount() > hy && rc.py.page != x[hy].py.page) { // first header would break the end of page
// TODO: header/footer adjustment here
rc.py.page++;
rc.py.y = rc.page.top;
}
clayout.hasheader = true;
rc.page.top = clayout.page.top = clayout.header[hy - 1].pyy.y + format.grid;
clayout.hasheader = true; // if it fits, we repeat header on each new page
rc.page.top = clayout.page.top = clayout.header[hy - 1].pyy.y + format.grid; // so have to reduce the page size for nonheader rows
}
}
clayout.page0 = rc.py.page;
@ -58,7 +60,7 @@ const RichTable::TabLayout& RichTable::Realize(RichContext rc) const
}
RichTable::Layout RichTable::Realize(RichContext rc, int ny) const
{
{ // create layout for first ny rows
Layout tab;
int nx = format.column.GetCount();

View file

@ -10,7 +10,7 @@ RichTable::Format::Format()
framecolor = Black;
before = after = lm = rm = 0;
header = 0;
keep = false;
keep = newpage = newhdrftr = false;
}
#include "RichText.h"
@ -28,7 +28,7 @@ bool RichTable::RowPaint(PageDraw& pw, const RichStyles& st, const Layout& tab,
int i, int ny, const Rect& pg, VectorMap<int, Rect>& frr,
PaintInfo& pi, int pd, bool sel) const
{
RichContext rc(st);
RichContext rc(st, NULL);
const Array<RichCell>& row = cell[i];
const PaintRow& pr = tab[i];
rc.py = pr.py;
@ -134,7 +134,7 @@ void RichTable::Paint(PageDraw& pw, RichContext rc, const PaintInfo& _pi) const
int ny = cell.GetCount();
VectorMap<int, Rect> frr;
for(int i = 0; i < ny; i++)
if(RowPaint(pw, rc.styles, tab, i, ny, pg, frr, pi, 0, sel))
if(RowPaint(pw, *rc.styles, tab, i, ny, pg, frr, pi, 0, sel))
break;
Color gc = format.gridcolor;
@ -157,7 +157,7 @@ void RichTable::Paint(PageDraw& pw, RichContext rc, const PaintInfo& _pi) const
Draw& w = pw.Page(pgi);
if(pgi > tab.page0 && tab.hasheader)
for(int i = 0; i < hy; i++) {
RowPaint(pw, rc.styles, tab.header, i, hy, hpg, frr, pi, pgi, false);
RowPaint(pw, *rc.styles, tab.header, i, hy, hpg, frr, pi, pgi, false);
w.DrawRect(pg.left, hpg.bottom, pg.Width(), gridln, format.gridcolor);
}
Rect r = frr[i].Inflated(frameln);

View file

@ -2,13 +2,10 @@ class RichText : public RichTxt, public DeepCopyOption<RichText> {
RichStyles style;
String footer_hack; // ugly hack
mutable One<RichText> header, footer;
bool nolinks;
void Init();
Rect GetPageMinusHeaderFooter(const Rect& page) const;
void PaintHeaderFooter(PageDraw& pw, const Rect& page, const PaintInfo& pi,
int from_page, int to_page) const;
@ -42,7 +39,9 @@ public:
void CatPick(RichText&& p);
using RichTxt::CatPick;
RichContext Context(const Rect& page, PageY py) const;
RichContext Context(const Rect& page, PageY py, const String& header_qtf, const String& footer_qtf) const;
RichContext Context(const Rect& page, PageY py) const { return Context(page, py, header_qtf, footer_qtf); }
RichContext Context(const Rect& page) const { return Context(page, PageY(0, 0)); }
RichPos GetRichPos(int pos, int maxlevel = INT_MAX) const;
int operator[](int pos) const { return GetRichPos(pos).chr; }
@ -132,17 +131,6 @@ public:
static void Register(ClipboardType& type);
void PickHeader(RichText&& txt);
void PickFooter(RichText&& txt);
void SetHeaderQtf(const char *qtf);
void SetFooterQtf(const char *qtf);
void ClearHeader() { header.Clear(); }
void ClearFooter() { footer.Clear(); }
String GetHeaderQtf(byte charset = CHARSET_UTF8, dword options = QTF_ALL) const;
String GetFooterQtf(byte charset = CHARSET_UTF8, dword options = QTF_ALL) const;
const RichText *GetHeaderPtr() const { return ~header; }
const RichText *GetFooterPtr() const { return ~footer; }
//Ugly hacks
void SetFooter(const String& s) { footer_hack = s; }
String GetFooter() const { return footer_hack; }

View file

@ -2,16 +2,6 @@
NAMESPACE_UPP
RichContext RichText::Context(const Rect& page, PageY py) const
{
RichContext c(style);
c.page = GetPageMinusHeaderFooter(page);
c.py = py;
if(py.y < c.page.top)
c.py.y = c.page.top;
return c;
}
PageY RichText::GetHeight(const Rect& page) const
{
return RichTxt::GetHeight(Context(page, PageY(0, 0)));
@ -114,13 +104,23 @@ bool RichText::GetInvalid(PageY& top, PageY& bottom, const Rect& page,
bottom = GetHeight(page);
return true;
}
#if 0
RichContext rc = Context(page, PageY(0, 0));
if(rtype == SPARA) {
rc.py = top = GetPartPageY(spi, rc);
bottom = GetNextPageY(spi, rc);
return true;
}
rc.py = top = GetPartPageY(r_parti, rc);
#endif
RichContext begin;
if(rtype == SPARA) { // selection changed within single paragraph
RichContext rc = GetPartContext(spi, Context(page));
top = rc.py;
bottom = GetAdvanced(spi, rc, begin).py;
return true;
}
RichContext rc = GetPartContext(r_parti, Context(page));
top = rc.py;
if(rtype == PARA) {
if(IsTable(r_parti))
switch(GetTable(r_parti).GetInvalid(top, bottom, rc)) {
@ -135,11 +135,11 @@ bool RichText::GetInvalid(PageY& top, PageY& bottom, const Rect& page,
const Para& pp = part[r_parti].Get<Para>();
if(r_paraocx == pp.ccx &&
r_paraocy == Sum(pp.linecy, 0) + pp.ruler + pp.before + pp.after &&
r_keep == pp.keep &&
r_keepnext == pp.keepnext &&
r_keep == pp.keep &&
r_keepnext == pp.keepnext &&
r_newpage == pp.newpage) {
bottom = GetNextPageY(r_parti, rc);
return true;
bottom = GetAdvanced(r_parti, rc, begin).py;
return true;
}
}
}

View file

@ -40,6 +40,7 @@ public:
RULER = 0x00004000,
RULERINK = 0x00002000,
RULERSTYLE= 0x00001000,
NEWHDRFTR = 0x00000800,
};
struct FormatInfo : RichPara::Format {
@ -84,6 +85,8 @@ protected:
mutable Bits spellerrors;
mutable bool checked;
mutable bool haspos;
mutable bool newhdrftr;
mutable String header_qtf, footer_qtf;
One<RichPara::NumberFormat> number;
void Invalidate();
@ -98,6 +101,7 @@ protected:
};
Vector<Part> part;
String header_qtf, footer_qtf;
mutable int length;
mutable int tabcount;
mutable Vector<PageY> py;
@ -132,8 +136,10 @@ protected:
void Sync0(const Para& pp, int parti, const RichContext& rc) const;
void Sync(int parti, const RichContext& rc) const;
bool BreaksPage(PageY py, const Para& pp, int i, const Rect& page) const;
PageY GetNextPageY(int parti, const RichContext& rc) const;
PageY GetPartPageY(int parti, RichContext rc) const;
void Advance(int parti, RichContext& rc, RichContext& begin) const;
RichContext GetAdvanced(int parti, const RichContext& rc, RichContext& begin) const;
RichContext GetPartContext(int parti, const RichContext& rc0) const;
PageY GetPartPageY(int parti, const RichContext& rc) const { return GetPartContext(parti, rc).py; }
struct ParaOp {
virtual bool operator()(RichTxt::Para& p) = 0;
@ -229,6 +235,13 @@ public:
Vector<int> GetAllLanguages() const;
WString GetPlainText(bool withcr = true) const;
void SetHeaderQtf(const char *qtf);
void SetFooterQtf(const char *qtf);
String GetHeaderQtf() const { return header_qtf; }
String GetFooterQtf() const { return footer_qtf; }
void ClearHeader() { SetHeaderQtf(NULL); }
void ClearFooter() { SetFooterQtf(NULL); }
struct UpdateIterator {
enum { CONTINUE = 0, STOP = 1, UPDATE = 2 };
virtual int operator()(int pos, RichPara& para) = 0;

View file

@ -86,7 +86,7 @@ void RichTxt::SetRefresh(int parti)
r_paraocy = Sum(pp.linecy, 0) + pp.before + pp.after;
r_keep = pp.keep;
r_keepnext = pp.keepnext;
r_newpage = pp.newpage;
r_newpage = pp.newpage || pp.header_qtf.GetCount() || pp.footer_qtf.GetCount();
break;
}
else

View file

@ -19,12 +19,11 @@ int RichTxt::GetWidth(const RichStyles& st) const
return cx;
}
void RichTxt::Sync0(const Para& pp, int parti, const RichContext& rc) const
{
int cx = rc.page.Width();
pp.ccx = cx;
RichPara p = Get(parti, rc.styles, false);
RichPara p = Get(parti, *rc.styles, false);
RichPara::Lines pl = p.FormatLines(cx);
pp.ruler = p.format.ruler;
pp.before = p.format.before;
@ -38,6 +37,9 @@ void RichTxt::Sync0(const Para& pp, int parti, const RichContext& rc) const
pp.keep = p.format.keep;
pp.keepnext = p.format.keepnext;
pp.orphan = p.format.orphan;
pp.newhdrftr = p.format.newhdrftr;
pp.header_qtf = p.format.header_qtf;
pp.footer_qtf = p.format.footer_qtf;
}
void RichTxt::Sync(int parti, const RichContext& rc) const {
@ -64,10 +66,22 @@ bool RichTxt::BreaksPage(PageY py, const Para& pp, int i, const Rect& page) cons
return false;
}
PageY RichTxt::GetNextPageY(int parti, const RichContext& rc) const
void RichTxt::Advance(int parti, RichContext& rc, RichContext& begin) const
{
if(part[parti].Is<RichTable>())
return GetTable(parti).GetHeight(rc);
if(part[parti].Is<RichTable>()) {
const RichTable& tab = GetTable(parti);
if(rc.text == this) {
if(tab.format.newhdrftr) {
rc.NewHeaderFooter(tab.format.header_qtf, tab.format.footer_qtf);
rc.Page();
}
else
if(tab.format.newpage)
rc.Page();
}
begin = rc;
rc.py = GetTable(parti).GetHeight(rc);
}
else {
Sync(parti, rc);
const Para& pp = part[parti].Get<Para>();
@ -76,7 +90,6 @@ PageY RichTxt::GetNextPageY(int parti, const RichContext& rc) const
cy += pp.cy;
else
cy += pp.linecy[0];
PageY py = rc.py;
if(rc.page.Height() < 30000) {
int nbefore = 0;
int nline = 0;
@ -86,38 +99,46 @@ PageY RichTxt::GetNextPageY(int parti, const RichContext& rc) const
nbefore = p.before + p.ruler;
nline = p.linecy[0];
}
if(pp.newpage || py.y + cy + nbefore + nline > rc.page.bottom && cy < rc.page.Height()) {
py.page++;
py.y = rc.page.top;
if(pp.newhdrftr && rc.text == this) {
rc.NewHeaderFooter(pp.header_qtf, pp.footer_qtf);
rc.Page();
}
py.y += pp.before + pp.ruler;
if(py.y + pp.cy < rc.page.bottom)
py.y += pp.cy;
else
if(pp.newpage && rc.text == this || rc.py.y + cy + nbefore + nline > rc.page.bottom && cy < rc.page.Height())
rc.Page();
begin = rc;
rc.py.y += pp.before + pp.ruler;
if(rc.py.y + pp.cy < rc.page.bottom)
rc.py.y += pp.cy;
else
for(int lni = 0; lni < pp.linecy.GetCount(); lni++) {
if(BreaksPage(py, pp, lni, rc.page)) {
py.y = rc.page.top;
py.page++;
}
py.y += pp.linecy[lni];
if(BreaksPage(rc.py, pp, lni, rc.page))
rc.Page();
rc.py.y += pp.linecy[lni];
}
py.y += pp.after;
if(py.y > rc.page.bottom) {
py.y = rc.page.top;
py.page++;
}
rc.py.y += pp.after;
if(rc.py.y > rc.page.bottom)
rc.Page();
}
else
py.y += pp.before + pp.cy + pp.after + pp.ruler;
return py;
rc.py.y += pp.before + pp.cy + pp.after + pp.ruler;
}
}
PageY RichTxt::GetPartPageY(int parti, RichContext rc) const
RichContext RichTxt::GetAdvanced(int parti, const RichContext& rc, RichContext& begin) const
{
RichContext r = rc;
Advance(parti, r, begin);
return r;
}
RichContext RichTxt::GetPartContext(int parti, const RichContext& rc0) const
{
RichContext begin;
RichContext rc = rc0;
for(int i = 0; i < parti; i++)
rc.py = GetNextPageY(i, rc);
return rc.py;
Advance(i, rc, begin);
return rc;
}
bool IsPainting(PageDraw& pw, Zoom z, const Rect& page, PageY top, PageY bottom)
@ -131,8 +152,9 @@ bool IsPainting(PageDraw& pw, Zoom z, const Rect& page, PageY top, PageY bottom)
PageY RichTxt::GetHeight(RichContext rc) const
{
RichContext begin;
for(int i = 0; i < GetPartCount(); i++)
rc.py = GetNextPageY(i, rc);
Advance(i, rc, begin);
return rc.py;
}
@ -146,8 +168,9 @@ void RichTxt::Paint(PageDraw& pw, RichContext& rc, const PaintInfo& _pi) const
if(part[parti].Is<RichTable>()) {
pi.tablesel--;
const RichTable& tab = GetTable(parti);
tab.Paint(pw, rc, pi);
rc.py = tab.GetHeight(rc);
RichContext begin;
Advance(parti, rc, begin);
tab.Paint(pw, begin, pi);
pi.tablesel -= tab.GetTableCount();
}
else {
@ -156,17 +179,10 @@ void RichTxt::Paint(PageDraw& pw, RichContext& rc, const PaintInfo& _pi) const
n.TestReset(*pp.number);
n.Next(*pp.number);
}
PageY next = GetNextPageY(parti, rc);
if(next >= pi.top) {
int nbefore = 0;
int nline = 0;
if(pp.keepnext && parti + 1 < part.GetCount() && part[parti + 1].Is<Para>()) {
Sync(parti + 1, rc);
const Para& pp = part[parti + 1].Get<Para>();
nbefore = pp.before;
nline = pp.linecy[0];
}
RichPara p = Get(parti, rc.styles, true);
RichContext begin;
RichContext next = GetAdvanced(parti, rc, begin);
if(next.py >= pi.top) {
RichPara p = Get(parti, *rc.styles, true);
if(pi.spellingchecker) {
if(!pp.checked) {
pp.spellerrors = (*pi.spellingchecker)(p);
@ -177,10 +193,10 @@ void RichTxt::Paint(PageDraw& pw, RichContext& rc, const PaintInfo& _pi) const
pp.checked = false;
pp.spellerrors.Clear();
}
if(IsPainting(pw, pi.zoom, rc.page, rc.py, next))
p.Paint(pw, rc.page, rc.py, pi, n, pp.spellerrors, nbefore, nline);
if(IsPainting(pw, pi.zoom, rc.page, begin.py, next.py))
p.Paint(pw, rc.page, begin.py, pi, n, pp.spellerrors, rc.text == this);
}
rc.py = next;
rc = next;
}
int l = GetPartLength(parti) + 1;
pi.highlightpara -= l;
@ -198,27 +214,19 @@ RichCaret RichTxt::GetCaret(int pos, RichContext rc) const
pos = GetLength();
while(parti < part.GetCount()) {
int l = GetPartLength(parti) + 1;
RichContext begin;
Advance(parti, rc, begin);
if(pos < l) {
if(IsTable(parti))
return GetTable(parti).GetCaret(pos, rc);
return GetTable(parti).GetCaret(pos, begin);
else {
const Para& p = part[parti].Get<Para>();
int nbefore = 0;
int nline = 0;
if(p.keepnext && parti + 1 < part.GetCount() && part[parti + 1].Is<Para>()) {
Sync(parti + 1, rc);
const Para& pp = part[parti + 1].Get<Para>();
nbefore = pp.before + pp.ruler;
nline = pp.linecy[0];
}
RichCaret tp = Get(parti, rc.styles, true)
.GetCaret(pos, rc.page, rc.py, nbefore, nline);
tp.textpage = rc.page;
RichCaret tp = Get(parti, *rc.styles, true).GetCaret(pos, begin.page, begin.py);
tp.textpage = begin.page;
return tp;
}
}
parti++;
pos -= l;
rc.py = GetNextPageY(parti++, rc);
}
return RichCaret();
}
@ -229,33 +237,16 @@ int RichTxt::GetPos(int x, PageY y, RichContext rc) const
int pos = 0;
if(part.GetCount()) {
PageY nnext = GetNextPageY(parti, rc);
while(parti < part.GetCount()) {
PageY next = nnext;
if(parti + 1 < part.GetCount()) {
RichContext nrc = rc;
nrc.py = next;
nnext = GetNextPageY(parti + 1, nrc);
}
if(y < next || y.page < next.page) {
RichContext begin;
Advance(parti, rc, begin);
if(y < rc.py || y.page < rc.py.page)
if(IsTable(parti))
return GetTable(parti).GetPos(x, y, rc) + pos;
else {
int nbefore = 0;
int nline = 0;
if(part[parti].Get<Para>().keepnext && parti + 1 < part.GetCount() && IsPara(parti + 1)) {
Sync(parti + 1, rc);
const Para& pp = part[parti + 1].Get<Para>();
nbefore = pp.before + pp.ruler;
nline = pp.linecy[0];
}
return Get(parti, rc.styles, true)
.GetPos(x, y, rc.page, rc.py, nbefore, nline) + pos;
}
}
return GetTable(parti).GetPos(x, y, begin) + pos;
else
return Get(parti, *rc.styles, true).GetPos(x, y, begin.page, begin.py) + pos;
pos += GetPartLength(parti) + 1;
parti++;
rc.py = next;
}
}
@ -268,17 +259,12 @@ RichHotPos RichTxt::GetHotPos(int x, PageY y, int tolerance, RichContext rc) con
int pos = 0;
int ti = 0;
if(part.GetCount()) {
PageY nnext = GetNextPageY(parti, rc);
while(parti < part.GetCount()) {
PageY next = nnext;
if(parti + 1 < part.GetCount()) {
RichContext nrc = rc;
nrc.py = next;
nnext = GetNextPageY(parti + 1, nrc);
}
if(y < next || y.page < next.page) {
RichContext begin;
RichContext next = GetAdvanced(parti, rc, begin);
if(y < next.py || y.page < next.py.page) {
if(IsTable(parti)) {
RichHotPos pos = GetTable(parti).GetHotPos(x, y, tolerance, rc);
RichHotPos pos = GetTable(parti).GetHotPos(x, y, tolerance, begin);
pos.table += ti + 1;
return pos;
}
@ -289,7 +275,7 @@ RichHotPos RichTxt::GetHotPos(int x, PageY y, int tolerance, RichContext rc) con
ti += 1 + GetTable(parti).GetTableCount();
pos += GetPartLength(parti) + 1;
parti++;
rc.py = next;
rc = next;
}
}
@ -314,7 +300,7 @@ int RichTxt::GetVertMove(int pos, int gx, RichContext rc, int dir) const
}
while(pi < GetPartCount()) {
int q = IsTable(pi) ? GetTable(pi).GetVertMove(p, gx, rc, dir)
: Get(pi, rc.styles, true).GetVertMove(p, gx, rc.page, dir);
: Get(pi, *rc.styles, true).GetVertMove(p, gx, rc.page, dir);
if(q >= 0)
return q + pos;
if(dir > 0)
@ -333,27 +319,21 @@ void RichTxt::GatherValPos(Vector<RichValPos>& f, RichContext rc, int pos, int t
{
int parti = 0;
while(parti < part.GetCount()) {
RichContext begin;
Advance(parti++, rc, begin);
if(part[parti].Is<RichTable>())
GetTable(parti).GatherValPos(f, rc, pos, type);
GetTable(parti).GatherValPos(f, begin, pos, type);
else {
int nbefore = 0;
int nline = 0;
const Para& p = part[parti].Get<Para>();
if(p.keepnext && parti + 1 < part.GetCount() && IsPara(parti + 1)) {
Sync(parti + 1, rc);
const Para& pp = part[parti + 1].Get<Para>();
nbefore = pp.before + pp.ruler;
nline = pp.linecy[0];
}
if(p.haspos) {
if(p.haspos)
if(type == LABELS)
Get(parti, rc.styles, true).GatherLabels(f, rc.page, rc.py, pos, nbefore, nline);
Get(parti, *begin.styles, true).GatherLabels(f, begin.page, begin.py, pos);
else
Get(parti, rc.styles, true).GatherIndexes(f, rc.page, rc.py, pos, nbefore, nline);
}
Get(parti, *begin.styles, true).GatherIndexes(f, begin.page, begin.py, pos);
}
pos += GetPartLength(parti) + 1;
rc.py = GetNextPageY(parti++, rc);
}
}

View file

@ -403,7 +403,12 @@ style).]
code. Example: [*C@3 `"`[l200;4 `"]]
::^ [s1; [%-C s][/C@(0.0.255) number]&]
[s0; [%-C@(128.0.255) s][/C@(0.0.255) `"text`"]]
:: [s0; Paragraph style, either defined by style number, or style name.]}}&]
:: [s0; Paragraph style, either defined by style number, or style name.]
:: [s0;%- [C tP][/C@(0.0.255) qtf][C@(128.0.255) `^`^][/C@(0.0.255) qtf][C@(128.0.255) `^`^]]
:: [s0; New text header / footer, [%-/C@(0.0.255) qtf] is complete embeded
QTF representing header/footer. This QTF can contain field[@5
`{:VALUE:PAGENUMBER:`} ]to represent page number and[@5 `{:VALUE:PAGECOUNT:`}]
to represent total number of pages.]}}&]
[s0;3 &]
[s0;3 &]
[s2; Styles&]
@ -629,14 +634,15 @@ as table start/stop and [@(128.0.255) `|`| `-`-] to divide cells/lines.
&]
[s0;3 &]
[s0;3 &]
[s2; Header and Footer&]
[s2; Global Header and Footer&]
[s0; &]
[s0; Global text header is defined using [%-C@(128.0.255) `^H][%-/C@(0.0.255) qtf`_text][%-C@(128.0.255) `^
`^], footer [%-C@(128.0.255) `^F][%-/C@(0.0.255) qtf`_text][%-C@(128.0.255) `^`^],
where [%-C@(128.0.255) H][%-/C@(0.0.255) qtf`_text] is complete embeded
QTF representing header/footer. This QTF can contain field[@5
`{:VALUE:PAGENUMBER:`} ]to represent page number and[@5 `{:VALUE:PAGECOUNT:`}]
to represent total number of pages.&]
where [%-/C@(0.0.255) qtf`_text] is complete embeded QTF representing
header/footer. This QTF can contain field[@5 `{:VALUE:PAGENUMBER:`}
]to represent page number and[@5 `{:VALUE:PAGECOUNT:`}] to represent
total number of pages. Global page header and footer can be changed
by paragraph attributes.&]
[s0;3 &]
[s0;3 &]
[s0;3 &]