#include "Browser.h" TopicLink TopicEditor::ParseTopicFilePath(const String& path) { TopicLink tl; tl.topic = GetFileTitle(path); String q = GetFileFolder(path); tl.group = GetFileTitle(q); q = GetFileFolder(q); for(int i = 0; i < packagedir.GetCount(); i++) if(PathIsEqual(packagedir[i], q)) { tl.package = package[i].name; return tl; } return TopicLink(); } String TopicEditor::ActualPackageDir() { return package.IsCursor() ? packagedir[package.GetCursor()] : Null; } struct ListOrder : FileList::Order { public: virtual bool operator()(const FileList::File& a, const FileList::File& b) const { return ToUpper(a.name) < ToUpper(b.name); } }; void LoadGroups(FileList& group, const String& dir) { FindFile ff(AppendFileName(dir, "*.tpp")); while(ff) { if(ff.IsFolder()) { group.Add(GetFileTitle(ff.GetName()), TopicImg::Group()); group.Enable(); } ff.Next(); } group.Sort(ListOrder()); } void TopicEditor::EnterPackage() { String pg = group.GetCurrentName(); group.Clear(); group.Disable(); topic.Clear(); topic.Disable(); if(!package.IsCursor()) return; group.Enable(); topic.Enable(); LoadGroups(group, ActualPackageDir()); if(!IsNull(pg)) group.FindSetCursor(pg); EnterGroup(); } void LoadTopics(FileList& topic, const String& dir, const String& filepath) { FindFile ff(AppendFileName(dir, "*.tpp")); while(ff) { if(ff.IsFile()) { topic.Add(GetFileTitle(ff.GetName()), TopicImg::Topic()); if(PathIsEqual(AppendFileName(dir, ff.GetName()), filepath)) topic.SetCursor(topic.GetCount() - 1); } ff.Next(); } topic.Sort(ListOrder()); } void TopicEditor::EnterGroup() { topic.Clear(); if(!package.IsCursor() || IsNull(group.GetCurrentName())) return; LoadTopics(topic, AppendFileName(ActualPackageDir(), group.GetCurrentName() + ".tpp"), filepath); topic.Enable(); } String TopicEditor::GetCurrentTopicPath() { return NormalizePath( AppendFileName( AppendFileName(ActualPackageDir(), group.GetCurrentName() + ".tpp"), topic.GetCurrentName() + ".tpp")); } void TopicEditor::ShowTopic(bool b) { title.Enable(b); title.Show(b); editor.Enable(b); editor.Show(b); } void TopicEditor::EnterTopic() { HideTopic(); if(!topic.IsCursor()) return; String h = GetCurrentTopicPath(); if(h != filepath) Load(h); else ShowTopic(); } void TopicEditor::Load(const String& fn) { Flush(); Topic t = ReadTopic(LoadFile(fn)); if(t.text.IsVoid()) { Exclamation("Error loading the topic file:&[* " + DeQtf(fn)); topic.KillCursor(); return; } title <<= t.title; editor <<= t.text; filepath = fn; AddLru(); int q = editstate.Find(fn); if(q >= 0) { FileInfo& fi = editstate[q]; if(fi.time == FileGetTime(fn)) { editor.SetPickUndoInfo(fi.undo); fi.time = Time(1, 1, 1); } editor.SetPosInfo(fi.pos); } ShowTopic(); ActiveFocus(editor); editor.ClearModify(); title.ClearModify(); Title(fn); } bool TopicEditor::Open(const String& fn) { TopicLink tl = ParseTopicFilePath(fn); if(!tl) return false; package.FindSetCursor(tl.package); group.FindSetCursor(tl.group); topic.FindSetCursor(tl.topic); return true; } bool TopicEditor::OpenLink(const String& lnk) { TopicLink tl = ParseTopicLink(lnk); if(!tl) return false; package.FindSetCursor(tl.package); group.FindSetCursor(tl.group); topic.FindSetCursor(tl.topic); return true; } void TopicEditor::Save() { if(IsNull(filepath)) return; if(IsNull(~title)) { const RichText& txt = editor.Get(); if(txt.IsPara(0)) { RichPara para = txt.Get(0); WString t; for(int i = 0; i < para.GetCount(); i++) if(para[i].IsText()) for(const wchar *s = para[i].text; *s; s++) if(*s == '\t' || *s == 160) t.Cat(' '); else if(*s >= ' ') t.Cat(*s); if(!IsNull(t)) title <<= t; } } if(!editor.IsModified() && !title.IsModified()) return; String r = WriteTopic((String)~title, editor.Get()); if(LoadFile(filepath) != r) { SaveFile(filepath, r); TopicLink tl = ParseTopicFilePath(filepath); if(tl) { SyncTopicFile(editor.Get(), TopicLinkString(tl), filepath, ~title); WhenSync(); } } } void TopicEditor::Flush() { Save(); FileInfo& fi = editstate.GetAdd(filepath); fi.time = FileGetTime(filepath); fi.pos = editor.GetPosInfo(); fi.undo = editor.PickUndoInfo(); filepath.Clear(); editor.Clear(); HideTopic(); } void TopicEditor::SaveInc(const String& packagedir, const String& group) { if(IsNull(packagedir) || IsNull(group)) return; String gh; FindFile ff(AppendFileName(AppendFileName(packagedir, group + ".tpp"), "*.tpp")); while(ff) { if(ff.IsFile()) { gh << "TOPIC(" << AsCString(GetFileTitle(ff.GetName())) << ")\r\n"; gh << "#include \"" << ff.GetName() << "\"\r\n"; gh << "END_TOPIC\r\n\r\n"; } ff.Next(); } String fn = AppendFileName(AppendFileName(packagedir, group + ".tpp"), "all.i"); if(LoadFile(fn) != gh) if(IsNull(gh)) DeleteFile(fn); else SaveFile(fn, gh); }