]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/DEVEL/mathml_editor/src/TDocument.cc
Initial revision
[helm.git] / helm / DEVEL / mathml_editor / src / TDocument.cc
diff --git a/helm/DEVEL/mathml_editor/src/TDocument.cc b/helm/DEVEL/mathml_editor/src/TDocument.cc
new file mode 100644 (file)
index 0000000..4c3bbba
--- /dev/null
@@ -0,0 +1,155 @@
+
+#include <sstream>
+
+#include "globals.hh"
+#include "dom.hh"
+#include "TDocument.hh"
+
+TDocument::TDocument()
+{
+  DOM::DOMImplementation di;
+  DOM::DocumentType dt;
+  doc = di.createDocument(TML_NS_URI, "tml:tex", dt);
+  DOM::Element root = doc.get_documentElement();
+  root.setAttributeNS(XMLNS_NS_URI, "xmlns:tml", TML_NS_URI);
+  assert(root);
+
+  DOM::EventTarget et(doc);
+  assert(et);
+  et.addEventListener("DOMSubtreeModified", *this, false);
+}
+
+TDocument::~TDocument()
+{
+  //DOM::Element root = doc.get_documentElement();
+  DOM::EventTarget et(doc);
+  assert(doc);
+  et.removeEventListener("DOMSubtreeModified", *this, false);
+}
+
+void
+TDocument::serialize(const char* filename) const
+{
+  DOM::DOMImplementation di;
+  di.saveDocumentToFile(doc, filename, GDOME_SAVE_LIBXML_INDENT);
+}
+
+TNode
+TDocument::create(const std::string& name, unsigned id) const
+{
+  DOM::Element elem = doc.createElementNS(TML_NS_URI, "tml:" + name);
+  if (id > 0)
+    {
+      ostringstream os;
+      os << "I" << id;
+      elem.setAttribute("id", os.str());
+    }
+  return elem;
+}
+
+TNode
+TDocument::createC(const std::string& name, unsigned id) const
+{
+  TNode m = create("c", id);
+  m["name"] = name;
+  return m;
+}
+
+TNode
+TDocument::createT(const std::string& name, const std::string& text, unsigned id) const
+{
+  TNode t = create(name, id);
+  t["val"] = text;
+  return t;
+}
+
+unsigned
+TDocument::nodeDepth(const DOM::Node& node)
+{
+  DOM::Node n = node;
+
+  unsigned depth = 0;
+  while (n)
+    {
+      depth++;
+      n = n.get_parentNode();
+    }
+  return depth;
+}
+
+DOM::Node
+TDocument::findCommonAncestor(const DOM::Node& node1, const DOM::Node& node2)
+{
+  DOM::Node n1 = node1;
+  DOM::Node n2 = node2;
+
+  unsigned d1 = nodeDepth(n1);
+  unsigned d2 = nodeDepth(n2);
+
+  cout << "finding common ancestor " << d1 << " " << d2 << endl;
+
+  while (d1 < d2)
+    {
+      assert(n2);
+      n2 = n2.get_parentNode();
+      d2--;
+    }
+
+  while (d1 > d2)
+    {
+      assert(n1);
+      n1 = n1.get_parentNode();
+      d1--;
+    }
+
+  while (n1 != n2)
+    {
+      assert(n1);
+      assert(n2);
+      n1 = n1.get_parentNode();
+      n2 = n2.get_parentNode();
+    }
+
+  return n1;
+}
+
+DOM::Node
+TDocument::findIdNode(const DOM::Node& node)
+{
+  DOM::Node n = node;
+  while (n)
+    {
+      if (n.get_nodeType() == DOM::Node::ELEMENT_NODE)
+       {
+         DOM::Element el = n;
+         if (el.hasAttribute("id")) return el;
+       }
+      n = n.get_parentNode();
+    }
+
+  return DOM::Node(0);
+}
+
+void
+TDocument::handleEvent(const DOM::Event& ev)
+{
+  DOM::MutationEvent me(ev);
+  assert(me);
+
+  if (dirty)
+    cout << "TDocument::handleEvent DIRTY BEFORE = " << dirty.getAttribute("id") << endl;
+  else
+    cout << "TDocument::handleEvent DIRTY BEFORE = (nil)" << endl;
+
+  if (DOM::Node node = me.get_target())
+    if (dirty)
+      dirty = findIdNode(findCommonAncestor(dirty, node));
+    else
+      dirty = findIdNode(node);
+  else
+    assert(0);
+
+  cout << "TDocument::handleEvent target = " << DOM::Node(me.get_target()).get_nodeName() << " DIRTY AFTER = "
+       << dirty.getAttribute("id") << " ME = " << DOM::Node(me.get_target()).get_nodeName() << endl;
+  
+}