#include "ide.h" class JsonView : public TopWindow { typedef JsonView CLASSNAME; public: TreeCtrl tree; LineEdit view; FrameTop errorbg; Label error; public: JsonView(); virtual bool Key(dword key, int count); virtual void Close(); void Load(const String& json); void CopyPath(); void Serialize(Stream& s); private: void Reset(); String Load0(const String& json); int AddNode(int parent_id, const Value& id, const String& name, const Value& v); }; JsonView::JsonView() { Title("JSON view"); Sizeable().Zoomable(); Icon(IdeCommonImg::json()); Add(tree.SizePos()); Add(view.SizePos()); error.SetFont(Arial(20)).SetInk(Red); errorbg.Height(25).Add(error.SizePos()); view.SetReadOnly(); view.SetColor(LineEdit::PAPER_READONLY, SColorPaper()); tree.SetDisplay(QTFDisplay()); tree.NoRoot(); tree.WhenLeftDouble = THISBACK(CopyPath); } bool JsonView::Key(dword key, int count) { if(key == K_ESCAPE) { Close(); return true; } return false; } void JsonView::Load(const String& json) { Reset(); String parsingError = Load0(json); if(parsingError.GetCount() > 0) { parsingError.Set(0, ToLower(parsingError[0])); error = "Json parsing error: \"" + parsingError + "\"."; AddFrame(errorbg); view.Show(); view <<= json; return; } tree.Show(); tree.SetFocus(); } void JsonView::CopyPath() { int id = tree.GetCursor(); String path; while(id) { Value k = tree.Get(id); if(!IsNull(k)) { if(IsNumber(k)) path = "[" + AsString(k) + "]" + path; if(IsString(k)) path = "[" + AsCString(String(k)) + "]" + path; } id = tree.GetParent(id); } WriteClipboardText(path); } void JsonView::Serialize(Stream& s) { int version = 0; s / version; SerializePlacement(s); } void JsonView::Close() { StoreToGlobal(*this, "JSONview"); TopWindow::Close(); } void JsonView::Reset() { RemoveFrame(errorbg); view.Clear(); view.Hide(); tree.Clear(); tree.Hide(); } String JsonView::Load0(const String& json) { String parsingError; CParser p(json); try { tree.Open(AddNode(0, Null, "JSON", ParseJSON(p))); } catch(const CParser::Error& e) { parsingError << e; } return parsingError; } int JsonView::AddNode(int parent_id, const Value& id, const String& name, const Value& v) { if(IsError(v)) { // TODO: Replace with JsonExc or something that is more accurate in this situation. String errorText = GetErrorText(v); errorText.Remove(0, errorText.Find(" ") + 1); throw Exc(errorText); } else if(v.Is()) { ValueMap m = v; parent_id = tree.Add(parent_id, IdeCommonImg::JsonStruct(), id, "[G1 [* " + name); for(int i = 0; i < m.GetCount(); i++) AddNode(parent_id, m.GetKey(i), "[@B \1" + String(m.GetKey(i)) + "\1:]", m.GetValue(i)); } else if(v.Is()) { parent_id = tree.Add(parent_id, IdeCommonImg::JsonArray(), id, "[G1 [* " + name); for(int i = 0; i < v.GetCount(); i++) AddNode(parent_id, i, "[@c " + AsString(i) + ":]", v[i]); } else { String qtf = "[G1 [* " + name + "]"; Image img = IdeCommonImg::JsonNumber(); if(IsString(v)) { img = IdeCommonImg::JsonString(); if(IsNull(v)) qtf << "[*@g Null"; else qtf << "[@r \1 " + AsCString(String(v)); } else { if(v.Is()) img = IdeCommonImg::JsonBool(); if(IsNull(v)) qtf << "[*@g Null"; else qtf << "\1 " + AsString(v); } parent_id = tree.Add(parent_id, img, id, qtf); } return parent_id; } void Ide::Json() { JsonView& dlg = CreateNewWindow(); dlg.Load(editor.IsSelection() ? editor.GetSelection() : editor.Get()); LoadFromGlobal(dlg, "JSONview"); dlg.OpenMain(); }