void ShowQTF(const String& qtf, const char *title) { RichText txt = ParseQTF(qtf); ClearClipboard(); AppendClipboard(ParseQTF(qtf)); WithStatLayout<TopWindow> dlg; CtrlLayoutOK(dlg, title); dlg.stat = qtf; dlg.Sizeable().Zoomable(); dlg.Run(); }
//============================================================================================== // writeLine treats all input as QTF data, so escape values properly before calling. void LogWin::writeLine(String line, bool embellish/* = false */) { //http://www.ultimatepp.org/srcdoc$RichText$QTF$en-us.html if (!activated) return; UrpEdit &re = logText; // Bug: U++ editor not picking up RichEdit object for dev interface. Kludge. re.Select(INT_MAX, 0); // Take input that we know contains QTF codes and convert it to RichText. AsRichText treats incoming as escaped QTF (non-QTF) // @n = text color, \1 is the wrapper code for escaping text, & sign is new line, ` escapes a single character if (embellish) { re.PasteText(ParseQTF(CAT << "[@4 \1" << TimeStamp() << "\1] `- " << line << "&")); } else { re.PasteText(ParseQTF(CAT << line << "&")); } re.Select(INT_MAX, 0); }
void TopicEditor::InsertItem() { if(IsNull(topicpath)) return; Save(); ref.Title("Insert"); if(ref.item.IsCursor()) ref.item.SetFocus(); ref.item.MultiSelect(); ref.classlist.Show(); int c = ref.Execute(); if(c == IDCANCEL) return; if(c == IDYES) { String qtf = "&{{1 "; bool next = false; for(int i = 0; i < ref.scope.GetCount(); i++) { String s = ref.scope.Get(i, 1); if(*s != '<') { if(next) qtf << ":: "; qtf << DeQtf(s); next = true; } } qtf << "}}&"; editor.PasteText(ParseQTF(qtf)); return; } String qtf; if(ref.item.IsSelection()) { for(int i = 0; i < ref.item.GetCount(); i++) if(ref.item.IsSelected(i)) { const CppItemInfo& m = ref.GetItemInfo(i); qtf << CreateQtf(ref.GetCodeRef(i), m.name, m, GetLang()); } } else if(ref.item.IsCursor()) { const CppItemInfo& m = ref.GetItemInfo(); qtf << CreateQtf(ref.GetCodeRef(), m.name, m, GetLang()); } else return; editor.BeginOp(); editor.PasteText(ParseQTF(styles + qtf)); editor.PrevPara(); editor.PrevPara(); }
// go to a selected link void HelpViewer::showLink(String const &link) { Topic t = GetTopic(link); if(!IsNull(t.text)) { Zoom zoom; zoom.m = 160; zoom.d = 1000; String label = t.label; RichText txt = ParseQTF(t.text); contentsPane.Pick(txt, zoom); contentsPane.GotoLabel(label, true); int tocId = mainTocTree.Find(link); if(tocId >= 0) { // disable tocTree action on selecting cursor // otherwise we've got a recursive call mainTocTree.WhenSel.Clear(); mainTocTree.SetCursor(tocId); // re-enable tocTree action mainTocTree.WhenSel = THISBACK(tocLinkCb); // setup window title Title(mainTocTree.GetValue()); } } }
void GatherTpp::GatherRefLinks(const char *upp) { for(FindFile pff(AppendFileName(upp, "*.*")); pff; pff.Next()) { if(pff.IsFolder()) { String package = pff.GetName(); String pdir = AppendFileName(upp, package); TopicLink tl; tl.package = package; for(FindFile ff(AppendFileName(pdir, "*.tpp")); ff; ff.Next()) { if(ff.IsFolder()) { String group = GetFileTitle(ff.GetName() ); tl.group = group; String dir = AppendFileName(pdir, ff.GetName()); for(FindFile ft(AppendFileName(dir, "*.tpp")); ft; ft.Next()) { if(ft.IsFile()) { String path = AppendFileName(dir, ft.GetName()); tl.topic = GetFileTitle(ft.GetName()); String link = TopicLinkString(tl); ScanTopicIterator sti(&reflink); sti.link = link; ParseQTF(ReadTopic(LoadFile(path))).Iterate(sti); } } } } } } }
String GatherTpp::QtfAsHtml(const char *qtf, Index<String>& css, const VectorMap<String, String>& links, const VectorMap<String, String>& labels, const String& outdir, const String& fn) { return EncodeHtml(ParseQTF(qtf), css, links, labels, outdir, fn, Zoom(8, 40), escape, 40); }
void HelpWindow::Print() { #ifndef PLATFORM_PDA Topic t = AcquireTopic(topic); UPP::Print(ParseQTF(t.text), Size(3968, 6074), 0); #endif }
Size QTFDisplayCls::GetStdSize(const Value& q) const { Size sz; RichText txt = ParseQTF((String)q); txt.ApplyZoom(GetRichTextStdScreenZoom()); sz.cx = txt.GetWidth(); sz.cy = txt.GetHeight(Zoom(1, 1), sz.cx); return sz; }
void DrawSmartText(Draw& draw, int x, int y, int cx, const char *text, Font font, Color ink, int accesskey) { if(*text == '\1') { RichText txt = ParseQTF(text + 1, accesskey); txt.ApplyZoom(GetRichTextStdScreenZoom()); txt.Paint(Zoom(1, 1), draw, x, y, cx); return; } DrawTLText(draw, x, y, cx, ToUnicode(text, CHARSET_DEFAULT), font, ink, accesskey); }
Size QTFDisplayCls::RatioSize(const Value& q, int cx, int cy) const { if(cy == 0 && cx > 0) { RichText txt = ParseQTF((String)q); txt.ApplyZoom(GetRichTextStdScreenZoom()); return Size(cx, txt.GetHeight(Zoom(1, 1), cx)); } return GetStdSize(q); }
void SIC_GetQtfHeight(EscEscape& e) { int zoom = e.Int(0); e.CheckArray(0); String text = e[1]; int cx = e.Int(2); RichText doc; doc = ParseQTF(text);//!!!!! e = doc.GetHeight(Zoom(zoom, 1024), cx); }
void TopicEditor::InsertNew(const String& coderef) { const CppItem *m = GetCodeRefItem(coderef); if(!m) return; editor.BeginOp(); editor.PasteText(ParseQTF(styles + CreateQtf(coderef, m->name, *m, GetLang()))); editor.PrevPara(); editor.PrevPara(); }
void QTFDisplayCls::Paint(Draw& draw, const Rect& r, const Value& v, Color ink, Color paper, dword style) const { String s; s << "[@(" << ink.GetR() << "." << ink.GetG() << "." << ink.GetB() << ") " << v; RichText rtext = ParseQTF(s); rtext.ApplyZoom(GetRichTextStdScreenZoom()); draw.DrawRect(r, paper); draw.Clipoff(r); rtext.Paint(Zoom(1, 1), draw, 0, 0, r.Width()); draw.End(); }
Size GetSmartTextSize(const char *text, Font font, int cx) { if(*text == '\1') { Size sz; RichText txt = ParseQTF(text + 1); txt.ApplyZoom(GetRichTextStdScreenZoom()); sz.cx = min(cx, txt.GetWidth()); sz.cy = txt.GetHeight(Zoom(1, 1), sz.cx); return sz; } return GetTLTextSize(ToUnicode(text, CHARSET_DEFAULT), font); }
void TopicLinkDlg::Topic() { if(package.IsCursor() && group.IsCursor() && topic.IsCursor()) { link <<= LinkString(); RichText txt = ParseQTF(ReadTopic(LoadFile( NormalizePath( AppendFileName(PackageGroup(group.GetCurrentName()), topic.GetCurrentName() + ".tpp") ))).text); Vector<String> ref = GatherLabels(txt); label.Clear(); for(int i = 0; i < ref.GetCount(); i++) label.Add(ref[i]); } }
int GetSmartTextHeight(const char *s, int cx, Font font) { if(*s == '\1') { Size sz; RichText txt = ParseQTF(s + 1); txt.ApplyZoom(GetRichTextStdScreenZoom()); return txt.GetHeight(Zoom(1, 1), cx); } int cy = font.Info().GetHeight(); int h = cy; while(*s) { if(*s == '\n') h += cy; s++; } return h; }
String GatherTpp::GatherTopics(const char *topic, String& title) { int q = tt.Find(topic); if(q < 0) { Topic p = ReadTopic(LoadFile(TopicFileName(topic))); title = p.title; String t = p; if(IsNull(t)) return "index.html"; tt.Add(topic) = p; GatherLinkIterator ti(&(reflink)); ParseQTF(t).Iterate(ti); for(int i = 0; i < ti.link.GetCount(); i++) { String dummy; GatherTopics(ti.link[i], dummy); } } else title = tt[q].title; return TopicFileNameHtml(topic); }
bool HelpWindow::GoTo0(const String& link) { if(IsNull(link) || current_link == link) return true; Topic t = AcquireTopic(link); SetBar(); if(!IsNull(t.text)) { label = t.label; topic = t.link; Title(FromUtf8(t.title)); RichText txt = ParseQTF(t.text); FinishText(txt); view.Pick(pick(txt), zoom); view.GotoLabel(label, true); current_link = link; tree.FindSetCursor(topic); return true; } return false; }
void SyncTopicFile(const String& link) { String path = GetTopicPath(link); LLOG("SyncTopicFile " << link << " path: " << path); TopicInfo& ti = topic_info().GetPut(link); Time tm = FileGetTime(path); if(ti.path == ":ide:" || ti.path == path && ti.time == tm) return; String fn = TopicCacheName(path); if(FileGetTime(fn) > tm) { LLOG("Loading topic from cache"); ClearLinkRef(link); FileIn in(fn); LTIMING("Loading topic from cache"); if(in) { String s = in.GetLine(); if(s == tdx_version) { ti.title = in.GetLine(); ti.words.Clear(); ti.path = path; ti.time = tm; while(!in.IsEof()) { String x = in.GetLine(); if(IsNull(x)) break; AddLinkRef(link, x); } while(!in.IsEof()) { String x = in.GetLine(); if(IsNull(x)) break; ti.words.Add(TopicWordIndex(x)); } Sort(ti.words); return; } } } Topic tp = ReadTopic(LoadFile(path)); SyncTopicFile(ParseQTF(tp.text), link, path, tp.title); }
String GatherTpp::GatherTopics(const char *topic, String& title) { static StaticCriticalSection mapl; int q; INTERLOCKED_(mapl) q = tt.Find(topic); if(q < 0) { Topic p = ReadTopic(LoadFile(TopicFileName(topic))); title = p.title; String t = p; if(IsNull(t)) { String topicEng = ChangeTopicLanguage(topic, LNG_('E','N','U','S')); p = ReadTopic(LoadFile(TopicFileName(topicEng))); String tt = p; if(IsNull(tt)) return "index.html"; title = p.title; p.title += " (translated)"; String help = "topic://uppweb/www/contribweb$" + GetTopicLanguage(topic); p.text = String("{{1f1t0/50b0/50@(240.240.240) [<A2 ") + t_("This page has not been translated yet") + "]. " + "[^" + help + "^ [<A2 " + t_("Do you want to translate it?") + "]]}}&&" + p.text; } INTERLOCKED_(mapl) tt.Add(topic) = p; GatherLinkIterator ti(&reflink); ParseQTF(t).Iterate(ti); #ifdef MTC CoWork work; for(int i = 0; i < ti.link.GetCount(); i++) work & callback2(sGatherTopics, &tt, ti.link[i]); #else for(int i = 0; i < ti.link.GetCount(); i++) GatherTopics(ti.link[i]); #endif } else { INTERLOCKED_(mapl) title = tt[q].title; } return TopicFileNameHtml(topic); }
void PutQTF(DocReport& r, const char *qtf) { RichText text; text = ParseQTF(qtf); Size sz = r.GetPageSize(); Size pgsz = r.GetSize(); PageY end = text.GetHeight(pgsz); int lastpage = end.page; int x = (sz.cx - pgsz.cx) / 2; int y = (sz.cy - pgsz.cy) / 2; for(int i = 0; i <= lastpage; i++) { if(i) r.Page(); PrintPageDraw pw(r); pw.SetPage(i); PaintInfo paintinfo; paintinfo.top = PageY(i, 0); paintinfo.bottom = PageY(i + 1, 0); text.Paint(pw, Rect(Point(x, y), pgsz), paintinfo); } r.SetYPos(end.y); }
// Parses TOC and fills tocTree control bool HelpViewer::LoadTOC(String const &tocLink) { // TOC is composed by QTF lines with a TOC link and label text // lines not containing the TOC link are simply ignored // TOC level is represented by number of TABS contained // inside a line; zero tabs means toplevel, id 0 of tocTree Vector<int>ids; ids.Add(0); int curLevel = 0; int curId = 0; TreeCtrl tocTree; Topic t = GetTopic(tocLink); if(IsNull(t.text)) return false; String label = t.label; String topic = t.link; // sets toc root string from topic ticle tocTree.SetRoot(Null, t.title); // converts QTF to RichTxt, easier to analyze RichText txt = ParseQTF(t.text); // extract all paragraphs from RichTxt, skip other objects for(int iPart = 0; iPart < txt.GetPartCount(); iPart++) { String tocLine; String lineLink; if(!txt.IsPara(iPart)) continue; RichPara p = txt.Get(iPart); for(int iParaPart = 0; iParaPart < p.GetCount(); iParaPart++) { RichPara::Part ¶Part = p.part[iParaPart]; if(paraPart.format.link != "") lineLink = paraPart.format.link; if(paraPart.NonText()) continue; tocLine += paraPart.text.ToString(); } // if part contains no text nor link to topic stuffs, simply skip it if(tocLine == "" || lineLink == "" || !lineLink.StartsWith("topic:")) continue; // now we should count tabls to get TOC indent level int level = 0; int j; while( (j = tocLine.Find(0x09)) >= 0) { level++; tocLine.Remove(j); } // allows just SINGLE UPPER level change, i.e., deeper ONE level from current // for each step; backleveling is possible at any depth if(level > curLevel+1) return false; if(level > curLevel) { ids.Add(curId); curLevel++; } else while(curLevel > level) { curLevel--; ids.Pop(); } // add the line to correct tree node curId = tocTree.Add(ids.Top(), Null, Value(lineLink), Value(tocLine)); } // if the tree control is non empty, appends it to the main TOC TreeCtrl if(tocTree.GetChildCount(0)) AppendTOC(tocTree); // opens all content tree and display first item mainTocTree.OpenDeep(0); mainTocTree.SetCursor(2); // stores first topic at top of stack String curLink = mainTocTree.Get(); stack.Clear(); stack.Add(curLink); tos = 0; return true; }
void StyleManager::Set(const char *qtf) { RichText txt = ParseQTF(qtf); Set(txt); }
void RichEditHdrFtr::PageNumber() { PasteText(ParseQTF("{:VALUE:PAGENUMBER:}")); EvaluateFields(); }
void TopicEditor::FixTopic() { String nest; if(!EditText(nest, "Fix topic", "Nest")) return; CppBase& base = CodeBase(); int q = base.Find(nest); if(q < 0) { Exclamation("Nest not found"); return; } Array<CppItem>& n = base[q]; Index<String> natural; Vector<String> link; for(int i = 0; i < n.GetCount(); i++) { const CppItem& m = n[i]; String nat; if(m.virt) nat << "virtual "; if(m.kind == CLASSFUNCTION || m.kind == CLASSFUNCTIONTEMPLATE) nat << "static "; nat << m.natural; natural.Add(nat); link.Add(MakeCodeRef(nest, n[i].qitem)); } RichText result; const RichText& txt = editor.Get(); bool started = false; int l, h; if(editor.GetSelection(l, h)) { l = txt.FindPart(l); h = txt.FindPart(h); } else { l = 0; h = txt.GetPartCount(); } for(int i = 0; i < txt.GetPartCount(); i++) if(txt.IsPara(i)) { RichPara p = txt.Get(i); if(i >= l && i < h) { WString h = p.GetText(); String nat; const wchar *s = h; while(*s) if(*s == 160 || *s == ' ') { nat.Cat(' '); while(*s == 160 || *s == ' ') s++; } else nat.Cat(*s++); int q = nat.GetCount() ? natural.Find(nat) : -1; if(q >= 0) { started = true; const CppItem& m = n[q]; RichText h = ParseQTF(styles + ("[s7; &]" + CreateQtf(link[q], n[q].name, m, GetLang(), true))); if(h.GetPartCount()) h.RemovePart(h.GetPartCount() - 1); result.CatPick(pick(h)); } else if(!started || p.GetLength()) result.Cat(p); } else result.Cat(p); } else { RichTable b; b <<= txt.GetTable(i); result.CatPick(pick(b)); } RichPara empty; result.Cat(empty); editor.BeginOp(); editor.SetSelection(0, txt.GetLength()); editor.PasteText(result); }
void Report::PaintHF(Draw& w, int y, const char *qtf, int i) { RichText txt = ParseQTF(FormatHF(qtf, i)); txt.Paint(w, 0, y, GetSize().cx); }
void Report::Put(const char *qtf) { Put(ParseQTF(qtf)); }
int Report::GetHeightHF(const char *s) { RichText txt = ParseQTF(FormatHF(s, 9999)); return txt.GetHeight(GetSize().cx); }
void RichTextView::SetQTF(const char *qtf, Zoom z) { Pick(ParseQTF(qtf), z); }
void RichEditHdrFtr::PageCount() { PasteText(ParseQTF("{:VALUE:PAGECOUNT:}")); EvaluateFields(); }