#include #include struct FileTemplate { String filename; String condition; String text; }; enum { TEMPLATEITEM_ID, TEMPLATEITEM_FILENAME, TEMPLATEITEM_OPTION, TEMPLATEITEM_SELECT }; struct TemplateItem { String label; int type; String id; Vector value; String init; }; struct PackageTemplate { String name; bool main; Array item; Array file; }; int ReadTemplateType(CParser& p) { static char *nm[] = { "id", "filename", "option", "select" }; for(int i = 0; i < __countof(nm); i++) if(p.Id(nm[i])) return i; p.ThrowError("Unknown type"); return 0; } PackageTemplate ReadTemplate(const char *filename) { PackageTemplate pt; FileIn in(filename); String header; String l; for(;;) { if(in.IsEof()) break; l = in.GetLine(); if(l[0] == '@' && l[1] == '@') break; header << l << '\n'; } CParser p(header, filename); p.PassId("template"); pt.name = p.ReadString(); pt.main = pt.sub = false; for(;;) { if(p.Id("main")) pt.main = true; else if(p.Id("sub")) pt.sub = true; else break; } p.PassChar(';'); while(!p.IsEof()) { int type = ReadTemplateType(p); TemplateItem& m = pt.item.Add(); m.type = type; if(type == TEMPLATEITEM_SELECT) { p.PassChar('('); do m.value.Add(p.ReadString()); while(p.Char(',')); p.PassChar(')'); } m.label = p.ReadString(); m.id = p.ReadId(); if(p.Char('=')) { const char *b = p.GetPtr(); while(!p.IsChar(';')) { if(p.IsEof()) p.ThrowError("unexpected end of file"); p.SkipTerm(); } m.init = String(b, p.GetPtr()); } p.PassChar(';'); } for(;;) { pt.file.Add(); pt.file.Top().filename = l.Mid(2); for(;;) { if(in.IsEof()) return pt; l = in.GetLine(); if(l[0] == '@' && l[1] == '@') break; if(l[0] == '?' && l[1] == '?') pt.file.Top().condition = l.Mid(2); else pt.file.Top().text << l << "\r\n"; } } } struct AppPreview : Ctrl { virtual void Paint(Draw& w); virtual void Layout(); ScrollBar sb; struct Line : Moveable { String text; bool header; }; Vector line; void Scroll() { Refresh(); } void Clear() { line.Clear(); Refresh(); sb.Set(0); } void Add(const String& data, bool header = false); typedef AppPreview CLASSNAME; AppPreview() { SetFrame(InsetFrame()); AddFrame(sb); sb <<= THISBACK(Scroll); NoWantFocus(); } }; int NoCr(int c) { return c == '\r' ? 0 : c; } void AppPreview::Layout() { sb.SetTotal(line.GetCount()); sb.SetPage(GetSize().cy / ScreenInfo().GetFontInfo(Courier(12)).GetHeight()); } void AppPreview::Paint(Draw& w) { Size sz = GetSize(); FontInfo fi = w.GetFontInfo(Courier(12)); int y = 0; int i = sb; while(y < sz.cy) { bool hdr = i < line.GetCount() && line[i].header; w.DrawRect(0, y, sz.cx, fi.GetHeight(), hdr ? SLtCyan : SWhite); if(i < line.GetCount()) w.DrawText(0, y, line[i].text, hdr ? Arial(12).Bold().Italic() : Courier(12), SBlack); y += fi.GetHeight(); i++; } } void AppPreview::Add(const String& data, bool header) { Vector l = Split(Filter(data, NoCr), '\n', false); for(int i = 0; i < l.GetCount(); i++) { Line& q = line.Add(); const char *s = l[i]; while(*s == '\t') { q.text << " "; s++; } q.text << s; q.header = header; } Refresh(); Layout(); } #define LAYOUTFILE #include struct TemplateDlg : public WithTemplateLayout { AppPreview preview; Array pt; Array