/boxvivid/uppsrc/RichEdit/Formating.cpp
C++ | 627 lines | 578 code | 49 blank | 0 comment | 117 complexity | e829d35759849c3e3a48ab85edb1774a MD5 | raw file
Possible License(s): LGPL-2.1, BSD-2-Clause, BSD-3-Clause, LGPL-3.0
- #include "RichEdit.h"
- NAMESPACE_UPP
- void RichEdit::ApplyFormat(dword charvalid, dword paravalid)
- {
- if(IsReadOnly())
- return;
- RichText::FormatInfo f = formatinfo;
- f.charvalid = charvalid;
- f.paravalid = paravalid;
- if(objectpos >= 0) {
- ModifyFormat(objectpos, f, 1);
- Finish();
- }
- if(IsSelection()) {
- if(tablesel) {
- NextUndo();
- SaveTable(tablesel);
- text.ApplyTableFormatInfo(tablesel, cells, f);
- }
- else {
- int l = min(cursor, anchor);
- int h = max(cursor, anchor);
- RichPos rp = text.GetRichPos(h);
- if(rp.posinpara == 0 && h > l) {
- RichPos rp1 = text.GetRichPos(h - 1);
- if(InSameTxt(rp, rp1))
- h--;
- }
- ModifyFormat(l, f, h - l);
- }
- Finish();
- }
- else
- if(cursorp.paralen == 0) {
- ModifyFormat(cursor, f, 0);
- Finish();
- }
- else
- if(f.paravalid) {
- ModifyFormat(cursor, f, 0);
- Finish();
- }
- else
- RefreshBar();
- }
- void RichEdit::ApplyFormatInfo(const RichText::FormatInfo& fi)
- {
- fi.ApplyTo(formatinfo);
- formatinfo.charvalid |= fi.charvalid;
- formatinfo.paravalid |= fi.paravalid;
- ApplyFormat(fi.charvalid, fi.paravalid);
- }
- void RichEdit::Bold()
- {
- NextUndo();
- formatinfo.Bold(!(formatinfo.IsBold() && (formatinfo.charvalid & RichText::BOLD)));
- ApplyFormat(RichText::BOLD);
- }
- void RichEdit::Italic()
- {
- NextUndo();
- formatinfo.Italic(!(formatinfo.IsItalic() && (formatinfo.charvalid & RichText::ITALIC)));
- ApplyFormat(RichText::ITALIC);
- }
- void RichEdit::Underline()
- {
- NextUndo();
- formatinfo.Underline(!(formatinfo.IsUnderline() && (formatinfo.charvalid & RichText::UNDERLINE)));
- ApplyFormat(RichText::UNDERLINE);
- }
- void RichEdit::Strikeout()
- {
- NextUndo();
- formatinfo.Strikeout(!(formatinfo.IsStrikeout() && (formatinfo.charvalid & RichText::STRIKEOUT)));
- ApplyFormat(RichText::STRIKEOUT);
- }
- void RichEdit::Capitals()
- {
- NextUndo();
- formatinfo.capitals = !formatinfo.capitals && (formatinfo.charvalid & RichText::CAPITALS);
- ApplyFormat(RichText::CAPITALS);
- }
- void RichEdit::SetScript(int i)
- {
- NextUndo();
- formatinfo.sscript = i;
- ApplyFormat(RichText::SSCRIPT);
- }
- void RichEdit::SetFace()
- {
- NextUndo();
- formatinfo.Face(~face);
- ApplyFormat(RichText::FACE);
- SetFocus();
- }
- void RichEdit::SetHeight()
- {
- NextUndo();
- formatinfo.Height(PtToDot(~height));
- ApplyFormat(RichText::HEIGHT);
- SetFocus();
- }
- void RichEdit::SetInk()
- {
- NextUndo();
- formatinfo.ink = ~ink;
- ApplyFormat(RichText::INK);
- SetFocus();
- }
- void RichEdit::SetPaper()
- {
- NextUndo();
- formatinfo.paper = ~paper;
- ApplyFormat(RichText::PAPER);
- SetFocus();
- }
- void RichEdit::SetLanguage()
- {
- NextUndo();
- formatinfo.language = (int)~language;
- ApplyFormat(RichText::LANGUAGE);
- SetFocus();
- }
- void RichEdit::Language()
- {
- WithRichLanguageLayout<TopWindow> d;
- CtrlLayoutOKCancel(d, t_("Language"));
- d.lang <<= ~language;
- if(d.Run() != IDOK)
- return;
- formatinfo.language = (int)~d.lang;
- ApplyFormat(RichText::LANGUAGE);
- SetFocus();
- if(!language.HasKey((int)~d.lang)) {
- Vector<int> h;
- for(int i = 0; i < language.GetCount(); i++)
- h.Add(language.GetKey(i));
- h.Add(~d.lang);
- SetupLanguage(h);
- }
- }
- void RichEdit::IndentMark()
- {
- RichRuler::Marker m;
- int l = formatinfo.lm;
- int r = cursorc.textpage.Width() - formatinfo.rm;
- m.pos = l + formatinfo.indent;
- m.minpos = max(l, 0);
- m.maxpos = max(r - 120, 0);
- m.top = true;
- m.image = formatinfo.paravalid & RichText::INDENT ? RichEditImg::Indent()
- : RichEditImg::IndentMixed();
- ruler.Set(2, m);
- }
- void RichEdit::ReadFormat()
- {
- if(objectpos >= 0)
- formatinfo = text.GetFormatInfo(objectpos, 1);
- else
- if(IsSelection())
- if(tablesel)
- formatinfo = text.GetTableFormatInfo(tablesel, cells);
- else
- formatinfo = text.GetFormatInfo(min(cursor, anchor), abs(cursor - anchor));
- else {
- RichPos p = cursorp;
- if(cursor && p.posinpara)
- p = text.GetRichPos(cursor - 1);
- formatinfo.Set(p.format);
- }
- ShowFormat();
- }
- void RichEdit::ShowFormat()
- {
- RefreshBar();
- if(formatinfo.charvalid & RichText::FACE)
- face <<= formatinfo.GetFace();
- else
- face <<= Null;
- if(formatinfo.charvalid & RichText::HEIGHT)
- height <<= DotToPt(formatinfo.GetHeight());
- else
- height <<= Null;
- if(formatinfo.charvalid & RichText::LINK)
- hyperlink <<= formatinfo.link;
- else
- hyperlink <<= Null;
- if(formatinfo.charvalid & RichText::INDEXENTRY)
- indexentry <<= formatinfo.indexentry;
- else
- indexentry <<= Null;
- if(formatinfo.charvalid & RichText::INK)
- ink <<= formatinfo.ink;
- else
- ink <<= Null;
- if(formatinfo.charvalid & RichText::PAPER)
- paper <<= formatinfo.paper;
- else
- paper <<= Null;
- if(formatinfo.charvalid & RichText::LANG)
- language <<= (int)formatinfo.language;
- else
- language <<= Null;
- if(IsSelection())
- label <<= Null;
- else
- label <<= formatinfo.label;
- int l = formatinfo.lm;
- int r = cursorc.textpage.Width() - formatinfo.rm;
- RichRuler::Marker m;
- m.pos = l;
- m.minpos = 0;
- m.maxpos = max(r - formatinfo.indent - 120, 0);
- m.image = formatinfo.paravalid & RichText::LM ? RichEditImg::Margin() : RichEditImg::MarginMixed();
- ruler.Set(0, m);
- m.pos = r;
- m.minpos = max(l + formatinfo.indent + 120, 0);
- m.maxpos = cursorc.textpage.Width();
- m.image = formatinfo.paravalid & RichText::RM ? RichEditImg::Margin() : RichEditImg::MarginMixed();
- ruler.Set(1, m);
- IndentMark();
- int maxpos = 0;
- m.minpos = 0;
- m.deletable = true;
- if(formatinfo.paravalid & RichText::TABS) {
- for(int i = 0; i < formatinfo.tab.GetCount(); i++) {
- RichPara::Tab tab = formatinfo.tab[i];
- m.pos = tab.pos;
- if(tab.pos > maxpos)
- maxpos = tab.pos;
- switch(tab.align) {
- case ALIGN_LEFT:
- m.image = RichEditImg::LeftTab();
- break;
- case ALIGN_RIGHT:
- m.image = RichEditImg::RightTab();
- break;
- case ALIGN_CENTER:
- m.image = RichEditImg::CenterTab();
- break;
- }
- ruler.Set(i + 3, m);
- }
- ruler.SetTabs(maxpos, formatinfo.tabsize);
- ruler.SetCount(formatinfo.tab.GetCount() + 3);
- }
- else {
- ruler.SetTabs(INT_MAX / 2, 1);
- ruler.SetCount(3);
- }
- if(formatinfo.paravalid & RichText::STYLE)
- style <<= formatinfo.styleid;
- else
- style <<= Null;
- setstyle->Enable(!IsSelection());
- }
- void RichEdit::HighLightTab(int r)
- {
- RichRuler::Marker m = ruler[r + 3];
- RichPara::Tab tab = formatinfo.tab[r];
- m.image = tab.align == ALIGN_RIGHT ? RichEditImg::RightTabTrack() :
- tab.align == ALIGN_CENTER ? RichEditImg::CenterTabTrack() :
- RichEditImg::LeftTabTrack();
- ruler.Set(r + 3, m);
- }
- void RichEdit::Hyperlink()
- {
- String s = formatinfo.link;
- if(!IsSelection() && !IsNull(s) && cursorp.format.link == s && text[cursor] != '\n') {
- int l = cursor - 1;
- while(l >= 0 && text[l] != '\n' && text.GetRichPos(l).format.link == s)
- l--;
- l++;
- int h = cursor;
- while(h < text.GetLength() && text[h] != '\n' && text.GetRichPos(h).format.link == s)
- h++;
- if(l < h)
- Select(l, h - l);
- }
- WString linktext;
- WhenHyperlink(s, linktext);
- if(s != formatinfo.link || linktext.GetLength()) {
- formatinfo.link = s;
- hyperlink <<= s;
- NextUndo();
- ApplyFormat(RichText::LINK);
- if(linktext.GetLength()) {
- RemoveSelection();
- RichPara p;
- p.format = formatinfo;
- p.Cat(linktext, formatinfo);
- RichText txt;
- txt.SetStyles(text.GetStyles());
- txt.Cat(p);
- Insert(cursor, txt, true);
- Move(cursor + linktext.GetCount(), false);
- }
- }
- SetFocus();
- }
- void RichEdit::Label()
- {
- if(IsSelection()) return;
- String s = formatinfo.label;
- WhenLabel(s);
- if(s != formatinfo.label) {
- formatinfo.label = s;
- NextUndo();
- ApplyFormat(0, RichText::LABEL);
- SetFocus();
- }
- }
- void RichEdit::IndexEntry()
- {
- if(EditText(formatinfo.indexentry, t_("Index Entry"), t_("Index entry"))) {
- indexentry <<= formatinfo.indexentry;
- ApplyFormat(RichText::INDEXENTRY);
- NextUndo();
- SetFocus();
- }
- }
- void RichEdit::BeginRulerTrack()
- {
- NextUndo();
- SaveFormat();
- int r = ruler.GetTrack();
- if(r < 0) return;
- RichRuler::Marker m = ruler[r];
- switch(r) {
- case 0:
- case 1:
- m.image = RichEditImg::MarginTrack();
- break;
- case 2:
- m.image = RichEditImg::IndentTrack();
- break;
- default:
- HighLightTab(r - 3);
- return;
- }
- ruler.Set(r, m);
- }
- void RichEdit::SetParaFormat(dword paravalid)
- {
- RichText::FormatInfo f = formatinfo;
- f.charvalid = 0;
- f.paravalid = paravalid;
- if(IsSelection())
- if(tablesel)
- text.ApplyTableFormatInfo(tablesel, cells, f);
- else
- text.ApplyFormatInfo(min(cursor, anchor), f, abs(cursor - anchor));
- else
- text.ApplyFormatInfo(cursor, f, 0);
- }
- void RichEdit::RulerTrack()
- {
- int r = ruler.GetTrack();
- if(r < 0) return;
- RichRuler::Marker m = ruler[r];
- switch(r) {
- case 0:
- formatinfo.lm = m.pos;
- SetParaFormat(RichText::LM);
- IndentMark();
- break;
- case 1:
- formatinfo.rm = cursorc.textpage.Width() - m.pos;
- SetParaFormat(RichText::RM);
- break;
- case 2:
- formatinfo.indent = m.pos - formatinfo.lm;
- SetParaFormat(RichText::INDENT);
- break;
- default:
- formatinfo.tab[r - 3].pos = m.pos;
- SetParaFormat(RichText::TABS);
- int maxpos = 0;
- for(int i = 0; i < formatinfo.tab.GetCount(); i++) {
- RichPara::Tab tab = formatinfo.tab[i];
- if(tab.pos > maxpos)
- maxpos = tab.pos;
- }
- ruler.SetTabs(maxpos, formatinfo.tabsize);
- break;
- }
- FinishNF();
- }
- void RichEdit::TabAdd(int align)
- {
- RichPara::Tab tab;
- tab.pos = ruler.GetPos();
- tab.align = align;
- if(formatinfo.tab.GetCount() > 30000 || tab.pos < 0 || tab.pos >= cursorc.textpage.Width()) return;
- formatinfo.tab.Add(tab);
- SetParaFormat(RichText::TABS);
- Finish();
- }
- void RichEdit::AddTab()
- {
- NextUndo();
- SaveFormat();
- TabAdd(ruler.GetNewTabAlign());
- }
- void RichEdit::TabMenu()
- {
- NextUndo();
- int r = ruler.GetTrack() - 3;
- if(r >= 0)
- HighLightTab(r);
- CallbackArgTarget<int> align;
- CallbackArgTarget<int> fill;
- MenuBar menu;
- menu.Add(t_("Left"), RichEditImg::LeftTab(), align[ALIGN_LEFT]);
- menu.Add(t_("Right"), RichEditImg::RightTab(), align[ALIGN_RIGHT]);
- menu.Add(t_("Center"), RichEditImg::CenterTab(), align[ALIGN_CENTER]);
- if(r >= 0) {
- int f = formatinfo.tab[r].fillchar;
- menu.Separator();
- menu.Add(t_("No fill"), fill[0])
- .Radio(f == 0);
- menu.Add(t_("Fill with ...."), fill[1])
- .Radio(f == 1);
- menu.Add(t_("Fill with ----"), fill[2])
- .Radio(f == 2);
- menu.Add(t_("Fill with __"), fill[3])
- .Radio(f == 3);
- menu.Separator();
- menu.Add(t_("Remove"), fill[-1]);
- }
- menu.Execute();
- if(!IsNull(align)) {
- SaveFormat();
- if(r >= 0) {
- formatinfo.tab[r].align = (int)align;
- SetParaFormat(RichText::TABS);
- }
- else
- TabAdd(align);
- }
- if(!IsNull(fill) && r >= 0) {
- SaveFormat();
- if(r >= 0) {
- if(fill == -1)
- formatinfo.tab[r].pos = Null;
- else
- formatinfo.tab[r].fillchar = (int)fill;
- SetParaFormat(RichText::TABS);
- }
- }
- Finish();
- }
- void RichEdit::AlignLeft()
- {
- NextUndo();
- formatinfo.align = ALIGN_LEFT;
- ApplyFormat(0, RichText::ALIGN);
- }
- void RichEdit::AlignRight()
- {
- NextUndo();
- formatinfo.align = ALIGN_RIGHT;
- ApplyFormat(0, RichText::ALIGN);
- }
- void RichEdit::AlignCenter()
- {
- NextUndo();
- formatinfo.align = ALIGN_CENTER;
- ApplyFormat(0, RichText::ALIGN);
- }
- void RichEdit::AlignJustify()
- {
- NextUndo();
- formatinfo.align = ALIGN_JUSTIFY;
- ApplyFormat(0, RichText::ALIGN);
- }
- void RichEdit::SetBullet(int bullet)
- {
- NextUndo();
- if((formatinfo.paravalid & RichText::BULLET) && formatinfo.bullet == bullet) {
- formatinfo.bullet = RichPara::BULLET_NONE;
- formatinfo.indent = formatinfo.paravalid & RichText::STYLE ?
- text.GetStyle(formatinfo.styleid).format.indent : 0;
- }
- else {
- formatinfo.bullet = bullet;
- formatinfo.indent = 150;
- }
- ApplyFormat(0, RichText::INDENT|RichText::BULLET);
- }
- void RichEdit::Style()
- {
- NextUndo();
- SaveFormat(cursor, 0);
- formatinfo.Set(text.GetStyle((Uuid)~style).format);
- ApplyFormat(0, RichText::STYLE);
- SetFocus();
- Finish();
- }
- void RichEdit::AdjustObjectSize()
- {
- NextUndo();
- RichObject obj = cursorp.object;
- if(!obj) return;
- WithObjectSizeLayout<TopWindow> d;
- CtrlLayoutOKCancel(d, t_("Object position"));
- Size sz = obj.GetSize();
- Size psz = obj.GetPhysicalSize();
- if(psz.cx == 0) psz.cx = 2000;
- if(psz.cy == 0) psz.cy = 2000;
- d.width.Set(unit, sz.cx);
- d.height.Set(unit, sz.cy);
- d.widthp.SetInc(5).Pattern("%.1f");
- d.widthp <<= 100.0 * sz.cx / psz.cx;
- d.heightp.SetInc(5).Pattern("%.1f");
- d.heightp <<= 100.0 * sz.cy / psz.cy;
- d.keepratio = obj.IsKeepRatio();
- d.width <<= d.height <<= d.widthp <<= d.heightp <<= d.Breaker(IDYES);
- d.ydelta.WithSgn().Set(unit, obj.GetYDelta());
- d.keepratio <<= d.Breaker(IDNO);
- for(;;) {
- switch(d.Run()) {
- case IDCANCEL:
- return;
- case IDYES:
- if(d.width.HasFocus() && !IsNull(d.width)) {
- d.widthp <<= 100 * (double)~d.width / psz.cx;
- if(d.keepratio) {
- d.height <<= psz.cy * (double)~d.width / psz.cx;
- d.heightp <<= ~d.widthp;
- }
- }
- if(d.height.HasFocus() && !IsNull(d.height)) {
- d.heightp <<= 100 * (double)~d.height / psz.cy;
- if(d.keepratio) {
- d.width <<= psz.cx * (double)~d.height / psz.cy;
- d.widthp <<= ~d.heightp;
- }
- }
- if(d.widthp.HasFocus() && !IsNull(d.widthp)) {
- d.width <<= psz.cx * (double)~d.widthp / 100;
- if(d.keepratio) {
- d.height <<= psz.cy * (double)~d.width / psz.cx;
- d.heightp <<= ~d.widthp;
- }
- }
- if(d.heightp.HasFocus() && !IsNull(d.heightp)) {
- d.height <<= psz.cy * (double)~d.heightp / 100;
- if(d.keepratio) {
- d.width <<= psz.cx * (double)~d.height / psz.cy;
- d.widthp <<= ~d.heightp;
- }
- }
- break;
- case IDNO:
- if(d.keepratio && !IsNull(d.width)) {
- d.widthp <<= 100 * (double)~d.width / psz.cx;
- if(d.keepratio) {
- d.height <<= psz.cy * (double)~d.width / psz.cx;
- d.heightp <<= ~d.widthp;
- }
- }
- break;
- case IDOK:
- if(!IsNull(d.width) && (int)~d.width >= 0)
- sz.cx = ~d.width;
- if(!IsNull(d.height) && (int)~d.height >= 0)
- sz.cy = ~d.height;
- obj.SetSize(sz);
- if(!IsNull(d.ydelta))
- obj.SetYDelta(~d.ydelta);
- obj.KeepRatio(d.keepratio);
- ReplaceObject(obj);
- return;
- }
- }
- }
- END_UPP_NAMESPACE