#include #ifdef PLATFORM_WIN32 #include "shellapi.h" #endif String promptTopic; Topic AcquireTopic(const String& topic) { TopicLink tl = ParseTopicLink(topic); String path = AppendFileName(AppendFileName(GetExeDirFile(""), tl.group + ".tpp"), tl.topic + ".tpp"); return ReadTopic(LoadFile(path)); } Topic ReadTopic(const char *text) { Topic topic; CParser p(text); try { while(!p.IsEof()) { if(p.Id("TITLE")) { p.PassChar('('); topic.title = p.ReadString(); p.PassChar(')'); } else if(p.Id("REF")) { p.PassChar('('); p.ReadString(); p.PassChar(')'); } else if(p.Id("TOPIC_TEXT")) { p.PassChar('('); topic.text << p.ReadString(); p.PassChar(')'); } else if(p.Id("COMPRESSED")) { StringBuffer b; b.Reserve(1024); while(p.IsInt()) { b.Cat(p.ReadInt()); p.PassChar(','); } topic.text = ZDecompress(b, b.GetLength()); } else { topic.text << p.GetPtr(); break; } } } catch(CParser::Error e) { topic.text = String::GetVoid(); topic.title = e; } return topic; } bool HelpWin::GoTo0(const String& link, bool find) { int q = link.Find('#'); if(q >= 0) { topic = link.Mid(0, q); label = link.Mid(q + 1); } else { topic = link; label = Null; } Topic t = AcquireTopic(topic); if(!IsNull(t.text)) { Title(t.title.ToWString()); view = t.text; view.GotoLabel(label, true); tree.FindSetCursor(topic); return true; } return false; } HelpWin::Pos HelpWin::GetPos() { Pos p; p.link = topic; p.scy = view.GetSb(); return p; } void HelpWin::GoTo(const String& link) { Pos p = GetPos(); if(GoTo0(link)) { if(!IsNull(p.link)) back.Add(p); forward.Clear(); SetBar(); return; } LaunchWebBrowser(link); } void HelpWin::Back() { Pos p = GetPos(); if(back.GetCount() && GoTo0(back.Top().link, false)) { if(back.GetCount()) { view.SetSb(back.Top().scy); back.Drop(); } if(!IsNull(p.link)) forward.Add(p); SetBar(); } } void HelpWin::Forward() { Pos p = GetPos(); if(forward.GetCount() && GoTo0(forward.Top().link, false)) { if(forward.GetCount()) { view.SetSb(forward.Top().scy); forward.Drop(); } if(!IsNull(p.link)) back.Add(p); SetBar(); } } void HelpWin::SetZoom() { zoom.d = 1000; view.SetZoom(zoom); Refresh(); } void HelpWin::FontSize() { int q = zoom.m / 20; if(q < 7 || q > 10) q = 7; else q++; zoom.m = 20 * q; SetZoom(); } void HelpWin::Print() { #ifdef PLATFORM_WIN32 ::Print(view.Get(), Size(3968, 6074), 0); #endif } void HelpWin::Tools(Bar& bar) { bar.Add(back.GetCount(), t_("Back"), commonImg::back_1_16(), THISBACK(Back)).Key(K_ALT_LEFT); bar.Add(forward.GetCount(), t_("Forward"), commonImg::forward_1_16(), THISBACK(Forward)).Key(K_ALT_RIGHT); bar.Gap(); bar.Add(t_("Font size"), commonImg::font_size_1_16(), THISBACK(FontSize)).Key(K_ALT_F); bar.Gap(); bar.Add(t_("Print"), commonImg::print_1_16(), THISBACK(Print)).Key(K_CTRL_P); } void HelpWin::SetBar() { toolbar.Set(THISBACK(Tools)); } bool HelpWin::Key(dword key, int) { if(key == K_ESCAPE) { Close(); return true; } return false; } void HelpWin::ClearTree() { tree_view.Zoom(1); tree.Clear(); } int HelpWin::AddTree(int parent, const Image& img, const String& topic, const String& title) { tree_view.NoZoom(); return tree.Add(parent, img, topic, title, false); } void HelpWin::FinishTree() { tree.FindSetCursor(topic); } void HelpWin::TreeCursor() { if(!IsNull(tree)) GoTo(~tree); } HelpWin::HelpWin() { tree_view.Horz(tree, view); tree_view.SetPos(2500); Add(tree_view.SizePos()); tree_view.Zoom(1); Sizeable().Zoomable(); Title(t_("Help in linea")); //view.Background(Color(255, 255, 232)); BackPaint(); view.WhenLink = THISBACK(GoTo); AddFrame(toolbar); zoom.m = 200; SetZoom(); view.Margins(2); tree <<= THISBACK(TreeCursor); tree.NoRoot(); Icon(commonImg::help_1_16()); SetBar(); } void HelpWin::SyncDocTree() { ClearTree(); VectorMap > map; String pdir = GetFileFolder(GetExeFilePath()) + "/"; for(FindFile ff(AppendFileName(pdir, "*.tpp")); ff; ff.Next()) if(ff.IsFolder()) { String group = GetFileTitle(ff.GetName()); String dir = AppendFileName(pdir, ff.GetName()); for(FindFile ft(AppendFileName(dir, "*.tpp")); ft; ft.Next()) { if(ft.IsFile()) { if(String(ft.GetName()).Mid(0, 1) != "_") map.GetAdd(group).Add(GetFileTitle(ft.GetName())); } } } for(int i = 0; i < map.GetCount(); i++) { Vector& group = map[i]; int pid; pid = AddTree(0, commonImg::group_1_16(), "topic://" + GetExeTitle() + "/" + map.GetKey(i), map.GetKey(i)); for(int j = 0; j < group.GetCount(); j++) { String t = "topic://" + GetExeTitle() + "/" + map.GetKey(i) + "/" + group[j]; String u = GetTopicTitle(GetFileFolder(GetExeFilePath()) + "/" + map.GetKey(i) + ".tpp/" + group[j] + ".tpp"); AddTree(pid, commonImg::topic_1_16(), t, u); } } FinishTree(); } void HelpWin::ShowTopics(const String& index) { SyncDocTree(); EnableTree(true); OpenHelp(index); return; } void HelpWin::OpenHelp(const String& topic) { if(!IsTreeEnabled()) ClearTree(); if(!IsOpen()) { Rect r = Ctrl::GetWorkArea(); Size s = r.Size(); r = r.CenterRect(s/2); SetRect(r); OpenMain(); } else SetForeground(); GoTo("topic://" + GetExeTitle() + "/" + topic); EnableTree(false); return; } String GetTopicTitle(const String &path) { FileIn in((char*)~path); if(!in) return ""; try { String ln = in.GetLine(); CParser p(ln); p.PassId("TITLE"); p.PassChar('('); String title = p.ReadString(); p.PassChar(')'); return title; } catch(CParser::Error&) {} }