]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/src/TDocument.cc
Initial revision
[helm.git] / helm / DEVEL / mathml_editor / src / TDocument.cc
1
2 #include <sstream>
3
4 #include "globals.hh"
5 #include "dom.hh"
6 #include "TDocument.hh"
7
8 TDocument::TDocument()
9 {
10   DOM::DOMImplementation di;
11   DOM::DocumentType dt;
12   doc = di.createDocument(TML_NS_URI, "tml:tex", dt);
13   DOM::Element root = doc.get_documentElement();
14   root.setAttributeNS(XMLNS_NS_URI, "xmlns:tml", TML_NS_URI);
15   assert(root);
16
17   DOM::EventTarget et(doc);
18   assert(et);
19   et.addEventListener("DOMSubtreeModified", *this, false);
20 }
21
22 TDocument::~TDocument()
23 {
24   //DOM::Element root = doc.get_documentElement();
25   DOM::EventTarget et(doc);
26   assert(doc);
27   et.removeEventListener("DOMSubtreeModified", *this, false);
28 }
29
30 void
31 TDocument::serialize(const char* filename) const
32 {
33   DOM::DOMImplementation di;
34   di.saveDocumentToFile(doc, filename, GDOME_SAVE_LIBXML_INDENT);
35 }
36
37 TNode
38 TDocument::create(const std::string& name, unsigned id) const
39 {
40   DOM::Element elem = doc.createElementNS(TML_NS_URI, "tml:" + name);
41   if (id > 0)
42     {
43       ostringstream os;
44       os << "I" << id;
45       elem.setAttribute("id", os.str());
46     }
47   return elem;
48 }
49
50 TNode
51 TDocument::createC(const std::string& name, unsigned id) const
52 {
53   TNode m = create("c", id);
54   m["name"] = name;
55   return m;
56 }
57
58 TNode
59 TDocument::createT(const std::string& name, const std::string& text, unsigned id) const
60 {
61   TNode t = create(name, id);
62   t["val"] = text;
63   return t;
64 }
65
66 unsigned
67 TDocument::nodeDepth(const DOM::Node& node)
68 {
69   DOM::Node n = node;
70
71   unsigned depth = 0;
72   while (n)
73     {
74       depth++;
75       n = n.get_parentNode();
76     }
77   return depth;
78 }
79
80 DOM::Node
81 TDocument::findCommonAncestor(const DOM::Node& node1, const DOM::Node& node2)
82 {
83   DOM::Node n1 = node1;
84   DOM::Node n2 = node2;
85
86   unsigned d1 = nodeDepth(n1);
87   unsigned d2 = nodeDepth(n2);
88
89   cout << "finding common ancestor " << d1 << " " << d2 << endl;
90
91   while (d1 < d2)
92     {
93       assert(n2);
94       n2 = n2.get_parentNode();
95       d2--;
96     }
97
98   while (d1 > d2)
99     {
100       assert(n1);
101       n1 = n1.get_parentNode();
102       d1--;
103     }
104
105   while (n1 != n2)
106     {
107       assert(n1);
108       assert(n2);
109       n1 = n1.get_parentNode();
110       n2 = n2.get_parentNode();
111     }
112
113   return n1;
114 }
115
116 DOM::Node
117 TDocument::findIdNode(const DOM::Node& node)
118 {
119   DOM::Node n = node;
120   while (n)
121     {
122       if (n.get_nodeType() == DOM::Node::ELEMENT_NODE)
123         {
124           DOM::Element el = n;
125           if (el.hasAttribute("id")) return el;
126         }
127       n = n.get_parentNode();
128     }
129
130   return DOM::Node(0);
131 }
132
133 void
134 TDocument::handleEvent(const DOM::Event& ev)
135 {
136   DOM::MutationEvent me(ev);
137   assert(me);
138
139   if (dirty)
140     cout << "TDocument::handleEvent DIRTY BEFORE = " << dirty.getAttribute("id") << endl;
141   else
142     cout << "TDocument::handleEvent DIRTY BEFORE = (nil)" << endl;
143
144   if (DOM::Node node = me.get_target())
145     if (dirty)
146       dirty = findIdNode(findCommonAncestor(dirty, node));
147     else
148       dirty = findIdNode(node);
149   else
150     assert(0);
151
152   cout << "TDocument::handleEvent target = " << DOM::Node(me.get_target()).get_nodeName() << " DIRTY AFTER = "
153        << dirty.getAttribute("id") << " ME = " << DOM::Node(me.get_target()).get_nodeName() << endl;
154   
155 }